I'd like to use properties for my instance variables, but in many cases, I only want the class itself to have access to the setter. I was hoping I could do something like this:
Foo.h:
@interface Foo {
NSString *bar;
}
@property (readonly) NSString *bar;
@end
Foo.m:
#import "Foo.h"
@interface Foo ()
@property (copy) NSString *bar;
@end
@implementation Foo
@synthesize bar;
@end
But this generates a warning:
Foo.m:4: warning: property ‘bar’ attribute in ‘Foo’ class continuation does not match class ‘Foo’ property
I can see what it's complaining about, but it still seems like a useful idiom. Is there some other way to accomplish this without writing my own setters?
The reason for declaring the getters and setters private is to make the corresponding part of the object's abstract state (i.e. the values) private. That's largely independent of the decision to use getters and setters or not to hide the implementation types, prevent direct access, etc.
Usually you want setters/getters to be public, because that's what they are for: giving access to data, you don't want to give others direct access to because you don't want them to mess with your implementation dependent details - that's what encapsulation is about.
The getter and setter method gives you centralized control of how a certain field is initialized and provided to the client, which makes it much easier to verify and debug. To see which thread is accessing and what values are going out, you can easily place breakpoints or a print statement.
Allowing the getter/setter to be passed around as lambda expressions rather than values. Getters and setters can allow different access levels - for example the get may be public, but the set could be protected.
Your approach is correct, but the redeclaration of @property bar
in the class extension must match the original declaration except for readwrite vs. readonly. So this will work:
Foo.h
@interface Foo {
NSString *bar;
}
@property (copy,readonly) NSString *bar;
@end
Foo.m:
#import "Foo.h"
@interface Foo ()
@property (copy,readwrite) NSString *bar;
@end
@implementation Foo
@synthesize bar;
@end
(recall that the default is assign
for properties, not copy
).
When Barry says "the default is retain for properties" he means that retain should be specified like this:
@property (retain) NSDate *endDate;
If they are left like this:
@property NSDate *endDate;
assign is assumed by the compiler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With