当我在现代Objective-C中重写setter和getter方法时,访问生成的实例变量出错。

21

我现在知道新的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文件中,对于我的另一个类(class 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;
}

要重写这个方法并添加一些自定义信息,但是它报错了 :-. 有什么想法吗?TIA。


1
我现在知道新的Objective-C编译器让你不再需要合成你的属性了。谢谢你说“编译器”而不是“Xcode”。终于有人明白了! - user529758
3个回答

35

如果你同时重载了setter和getter方法,编译器将不再自动为你创建实例变量。你可以像这样在类实现中添加它:

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

你有这方面的参考资料吗?你在哪里读到的?谢谢。 - sole007
@sole007,我记得几年前在现代化的Objective C WWDC视频中看到过它。 - Carl Veazey

5

1
你不必使用 @synthesize。你可以声明自己的 ivar。 - rmaddy
1
嗯,我会说你不需要声明iVars,你可以使用@synthesize。我想这取决于你的喜好。 - Jeffery Thomas
在最新的编译器之前,@synthesize 只会合成 setter 和 getter 方法,而不是实例变量 ivar。由于 OP 提供了这些方法,因此没有必要使用 @synthesize。在这种情况下,更清晰的做法是添加自己的 ivar。当大部分功能都未被使用时,为什么要使用 @synthesize?但最终,在最新的编译器中,@synthesize 会起作用。我主要反对您使用“need”这个词,因为事实上并不是这样。这是一种选择,而不是必须的。 - rmaddy
@rmaddy 不,@synthesize 如果不存在 iVar,它就会始终生成一个。我写了很多 @synthesize prop = _prop; 这样的代码行,从来不需要显式声明 iVar。我理解你对单词“need”的吹毛求疵,我会改变措辞。 - Jeffery Thomas

3

总结回答:

如果您覆盖了setter和getter,编译器将不会为您创建实例变量。

为什么?在这种情况下,编译器假定该属性是动态的:它可能是依赖于其他属性进行存储/计算的属性,或者将通过其他方式创建,例如使用Objective-C运行时函数在运行时创建。

为了帮助编译器更好地理解情况,有两个潜在的解决方案:

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

或者

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接