Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
517 views
in Technique[技术] by (71.8m points)

cocoa - Objective-C - readonly properties not synthesized with underscore ivar?

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:

main.m

#import <Foundation/Foundation.h>
#import "hello.h"

int main(int argc, char *argv[])
{

    @autoreleasepool {

        Hello *hello = [[Hello alloc] init];
        NSLog(@"%@", hello.myString);

        return 0;

    }

}

hello.h

#import <Foundation/Foundation.h>

@interface Hello : NSObject
@property (copy, nonatomic) NSString *myString;
@end

hello.m

#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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...