Подтвердить что ты не робот

Objective-C - свойства readonly, не синтезированные с подчеркиванием ivar?

Если я правильно понимаю, в Objective-C свойства автоматически синтезируются с помощью геттеров и сеттеров, при этом переменная экземпляра объявляется как имя свойства с добавленным подчеркиванием (_ivar).

Итак, этот код:

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

Может быть скомпилирован и запущен следующим образом:

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

Теперь, когда я изменяю свойство myString для readonly следующим образом:

@property (readonly, copy, nonatomic) NSString *myString;

Затем, когда я пытаюсь скомпилировать, я получаю сообщение об ошибке:

hello.m:11:9: error: unknown type name '_myString'; did you mean 'NSString'?
        _myString = @"Hello";
        ^~~~~~~~~
        NSString

Так что _myString не определено. Не компилятор не синтезировал свойство с переменной экземпляра _myString? Посмотрите, работает ли это, когда я сам синтезирую его:

В реализации hello.m:

@synthesize myString = _myString;

Теперь он снова работает:

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

Итак, мой вопрос: почему он не автоматически синтезируется с подчеркиванием ivar, когда вы используете readonly для свойств? Или я полностью ошибаюсь в понимании того, как это работает Objective-C?

Я очень благодарен за объяснительный ответ, поскольку я действительно хочу понять, что именно происходит и почему.

Спасибо заранее.

4b9b3361

Ответ 1

Свойство автоматически не синтезируется, если вы реализуете все необходимые методы доступа (getter для свойства только для чтения, getter + setter для свойства read-write).

Поскольку вы используете метод getter -(NSString *)myString для свойства только для чтения, он не автосинтезирован. Если вашему получателю нужна переменная экземпляра для резервного копирования значения свойства, вам нужно добавить оператор synhesize (как и вы) или переменную экземпляра.