Eiko和其他人给出了正确的答案。
这是一种更简单的方法:直接访问私有成员变量。
例
在标题.h文件中:
@property (strong, nonatomic, readonly) NSString* foo;
在实施.m文件中:
// inside one of my init methods
self->_foo = @"someString"; // Notice the underscore prefix of var name.
就这样,这就是您所需要的。没有混乱,没有大惊小怪。
细节
从Xcode 4.4和LLVM Compiler 4.0(Xcode 4.4中的新功能)开始,您无需弄混其他答案中讨论的琐事:
- 该
synthesize
关键字
- 声明一个变量
- 在实现.m文件中重新声明该属性。
声明属性后foo
,你可以假设Xcode中已添加下划线的前缀命名一个私有成员变量:_foo
。
如果声明了属性readwrite
,则Xcode生成名为的getter方法foo
和名为的setter setFoo
。当您使用点表示法(my Object.myMethod)时,将隐式调用这些方法。如果声明了该属性readonly
,则不会生成任何setter。这意味着以下划线命名的后备变量本身不是只读的。这readonly
意味着根本没有合成任何setter方法,因此使用点表示法设置值会失败,并出现编译器错误。点表示法失败,因为编译器阻止您调用不存在的方法(setter)。
解决此问题的最简单方法是直接访问用下划线命名的成员变量。即使不声明下划线命名的变量,您也可以这样做!Xcode会在构建/编译过程中插入该声明,因此您的已编译代码确实将具有变量声明。但是您永远不会在原始源代码文件中看到该声明。不是魔术,只是语法糖。
使用self->
是访问对象/实例的成员变量的方法。您也许可以省略它,而只需使用var名称。但是我更喜欢使用self + arrow,因为它可以使我的代码自我记录。当您看到时,self->_foo
您毫无疑问地知道_foo
该实例上的成员变量。
顺便说一句,关于属性访问器与直接ivar访问的优缺点的讨论,正是您在Matt Neuberg博士的《Programming iOS》一书中所读到的。我发现阅读和重新阅读非常有帮助。