iOS中iVars的只读属性存在奇怪问题

时间:2012-09-06 04:19:14

标签: objective-c ios

这就是我所拥有的:

@interface engine : NSObject
{

    int test;

}

@property (nonatomic, readonly) int test;

当我尝试在我自己的类(引擎类)中为iVar测试分配值(10)时,调试器显示test = 10,_test = 0。

当我尝试从测试中读取时,我得到0,我猜我得到了值of_test。

如何使其按预期方式工作?我希望外部类只能读取“test”,但在我的课程中,我可以为“test”分配和读取值吗?

或者这个实现有什么问题?

更新:我没有同步,因为我使用xcode 4.4,它自动为你做。我假设合成将使用相同的iVar名称作为属性。如果进行正常的合成,这是默认行为。

感谢。

3 个答案:

答案 0 :(得分:1)

很难说没有看到您的代码,但我猜,您正在尝试执行类似test=10而不是self.test=10的操作。根据您使用的ObjC / XCode的版本以及可能的@synthesize语句,您正在访问(定义的)局部变量,但不访问属性resp。这是iVar。

修改

如果要编写只读属性,则应使用其iVar。例如,在_test=10读取访问权限之后,self.test_test(但不是纯test!)应该提供相同的值。

答案 1 :(得分:1)

你认为错了。默认实现是使用下划线生成属性名称。如果你想要一个不同的名字,你需要自己合成它。

答案 2 :(得分:1)

自动合成会创建一个带下划线前缀的实例变量,因此名为test的属性会生成_test的后备实例变量。所以你有两个实例变量; test,未与该媒体资源相关联,_test。如果您写入实例变量test,它将不会反映在_test或属性的值中。

但更重要的是,自己声明支持实例变量毫无意义。这只是一个额外的代码和不必要的冗余。 @property行已包含类型,名称,是否为读/写或只读以及存储限定符。只需跳过自己声明支持实例变量并使用编译器为您生成的变量。

在Engine.h中:

@interface Engine : NSObject
@property (readonly, assign) NSInteger test;
- (void)doSomething;
@end

在Engine.m中:

@implementation Engine

- (void)doSomething {
    _test++; // _test is created automatically by the compiler
}

@end

在other.m中:

Engine *engine = [[Engine alloc] init];
NSLog(@"%d", engine.test); // 0
[engine doSomething];
NSLog(@"%d", engine.test); // 1

这一切都正常。不要添加它。