问题
@interface ViewController : UIViewController{
NSNumber *nmbr;
}
@property (nonatomic, readonly) NSNumber *nmbr;
- (NSNumber*)nmbr;
- (void)setNmbr:(NSNumber *)value;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setNmbr:[NSNumber numberWithInt:4]];
NSLog(@"Value of number is: %@", self.nmbr);
}
- (NSNumber*)nmbr{
return nmbr;
}
- (void)setNmbr:(NSNumber *)value{
nmbr = value;
}
@end
I am expecting the program not to let setNmbr function work because nmbr property in the interface file is readonly. But it is setting the value of nmbr. What wrong am I doing?
回答1:
The readonly
doesn't prevent you from writing your own setter. It simply prevents the compiler from synthesizing a setter for you. It would be nice if it warned you if you implemented a setter for a readonly
property, but it doesn't.
Clearly, it's inadvisable to implement a setter for a readonly
property. Furthermore, you generally wouldn't even declare the ivar nor implement the getter for the property, either, because those would both be synthesized for you (unless you were doing something special there, which you're not).
回答2:
If you are creating a property in objective-c, it creates 3 things for you.
- an instance variable which you can access by using an underscore before the property name. Ex:
_nmbr
- a getter method which you can call directly by using the property name. Ex:
[self nmbr];
this will actually call- (NSNumber *)nmbr {}
method. - a setter method which you can call by using a 'set' keyword before it. Ex:
[self setNmbr:@1];
this will actually call- (void)setNmbr:(NSNumber *)nmbr {}
method.
said that, you don't need to explicitly define getters and setters. Objective-C gives you these getters and setters by default.
You are able to access the setter in the above question because you are explicitly setting them which you need not do.
Hope this helps.
来源:https://stackoverflow.com/questions/29190154/why-readonly-property-setter-is-working-objective-c