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

Ошибка доступа к сгенерированным ivars при переопределении сеттеров и геттеров в Modern Objective-C

Теперь я знаю, что новый компилятор Objective-C позволяет вам больше не синтезировать свои свойства. У меня есть один файл, в котором есть два класса. Мой .h для простого вспомогательного класса выглядит следующим образом:

@interface ViewFrameModel : NSObject

@property (nonatomic, strong) UIView *view;
@property (nonatomic, assign) CGRect frame;

- (id)initWithView:(UIView *)view frame:(CGRect)frame;

@end

В том же файле .h для моего другого класса (класс 2) у меня есть:

@property (nonatomic, strong) ViewFrameModel *viewFrameModel;

В классе 2.m я могу это сделать:

- (void)setViewFrameModel:(ViewFrameModel *)viewFrameModel {
    _viewFrameModel = viewFrameModel;        
    [self pushViewFrameModel:viewFrameModel];
}

Это отлично работает без жалоб от компилятора, однако, когда я добавляю это:

- (ViewFrameModel *)viewFrameModel {
    return _viewFrameModel;
}

Я получаю две жалобы: по первому методу setViewFrameModel:

"Использование незаявленного идентификатора _viewFrameModel, вы имели в виду viewFrameModel"

И другой при возврате _viewFrameModel:

"Использование необъявленного идентификатора _viewFrameModel, вы имели в виду viewFrameModel" "Ссылка на локальную переменную viewFrameModel", объявленную в охватывающем контексте "

Почему я получаю эти ошибки, когда добавляю в

- (ViewFrameModel *)viewFrameModel {
    return _viewFrameModel;
}

метод? Я хочу переопределить этот метод с помощью некоторой пользовательской информации, но он жалуется на меня: -. Мысли? ТИА.

4b9b3361

Ответ 1

Если вы переопределяете как сеттер, так и получатель, компилятор больше не будет автоматически создавать переменную экземпляра. Вы можете добавить его в свою реализацию класса следующим образом:

@implementation ClassName {
    ViewFrameModel *_viewFrameModel;
}
...
@end

Ответ 2

Вот результаты некоторых тестов, которые я провел в прошлом году: iOS automatic @synthesize без создания ivar.

Короче говоря, вам нужно использовать @synthesize или явно объявить iVar.

Ответ 3

Подводя итог ответам:

Если вы переопределите как сеттер, так и получатель, компилятор не создаст для вас переменную экземпляра.

Почему? В этом случае компилятор предполагает, что свойство является динамическим: это может быть свойство, которое полагается на другие свойства для хранения/вычисления или что оно будет создано другими способами, например, во время выполнения с использованием Objective-C функций времени выполнения.

Чтобы помочь компилятору лучше понять ситуацию, существуют два возможных решения:

@implementation Class {
@synthesize property = _property;
...
@end

или

@implementation Class {
    PropertyClass *_property;
}
...
@end