在Modern Objective-C中覆盖setter和getter时访问生成的ivars时出错

时间:2013-01-08 20:05:52

标签: objective-c ios properties getter-setter

我现在知道新的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;
}

方法?我想用一些自定义信息覆盖这个方法,但它在抱怨我: - 。思考? TIA。

3 个答案:

答案 0 :(得分:34)

如果同时覆盖setter和getter,编译器将不再为您自动创建实例变量。您可以将其添加到类实现中,如下所示:

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

答案 1 :(得分:6)

以下是我去年进行的一些测试的结果:iOS automatic @synthesize without creating an ivar

简而言之,您需要使用@synthesize或明确声明iVar。

答案 2 :(得分:1)

总结答案:

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

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

为了帮助编译器更好地理解这种情况,有两种可能的解决方案:

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

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