Вопрос:

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

objective-c cocoa synthesize

6552 просмотра

1 ответ

23232 Репутация автора

Если я правильно понимаю, в Objective-C свойства автоматически синтезируются с помощью методов получения и установки, при этом переменная экземпляра объявляется как имя свойства с подчеркиванием prepended ( _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?

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

Заранее спасибо.

Автор: gitaarik Источник Размещён: 27.05.2013 11:41

Ответы (1)


55 плюса

433281 Репутация автора

Решение

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

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

Автор: Martin R Размещён: 27.05.2013 11:54
Вопросы из категории :
32x32