If I understand correctly, in Objective-C, properties are automatically synthesized with getters and setters, with the instance variable declared as the property name with an underscore prepended (_ivar
).
So, this code:
#import <Foundation/Foundation.h>
#import "hello.h"
int main(int argc, char *argv[])
{
@autoreleasepool {
Hello *hello = [[Hello alloc] init];
NSLog(@"%@", hello.myString);
return 0;
}
}
#import <Foundation/Foundation.h>
@interface Hello : NSObject
@property (copy, nonatomic) NSString *myString;
@end
#import "hello.h"
@implementation Hello
-(Hello *)init
{
if (self = [super init]) {
_myString = @"Hello";
}
return self;
}
-(NSString *)myString
{
return [NSString stringWithFormat:@"%@ %@", _myString, @"World"];
}
@end
Can be compiled and run like this:
bash-3.2$ clang -framework Foundation main.m hello.m -o hello
bash-3.2$ ./hello
2013-05-27 13:20:39.738 hello[23320:707] Hello World
Now when I change the myString property to readonly like this:
@property (readonly, copy, nonatomic) NSString *myString;
Then when I try to compile I get an error:
hello.m:11:9: error: unknown type name '_myString'; did you mean 'NSString'?
_myString = @"Hello";
^~~~~~~~~
NSString
So _myString
is not defined. Did the compiler not synthesize the property with instance variable _myString? Let's see if it works when I synthesize it myself:
In hello.m implementation:
@synthesize myString = _myString;
Now it works again:
bash-3.2$ clang -framework Foundation main.m hello.m -o hello
bash-3.2$ ./hello
2013-05-27 13:36:59.916 hello[24219:707] Hello World
So, my question is, why is it not automatically synthesized with an underscore ivar when you use readonly
on properties? Or am I totally on the wrong path of understanding how this Objective-C stuff works?
I would very much appreciate an explaining answer, as I really want to understand what's exactly happening and why.
Thank you in advance.
A property is not automatically synthesized if you implement all required accessor methods (getter for a read-only property, getter + setter for a read-write property).
Because you implement the getter method -(NSString *)myString
for the read-only property,
it is not auto-synthesized. If your getter needs an instance variable to backup the property value, you have to add the synthesize statement (as you did) or an instance variable.
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