使用ARC为ios声明readonly属性的正确方法是什么

Way*_*oda 16 properties object objective-c readonly automatic-ref-counting

我是iOS开发的新手,从未处理过手动引用计数(保留,释放,自动释放).因此,我对ARC的神奇表现并不了解.

我想我明白,直到有人问我是什么所有制类型(weak,strong,assign应给予一个只读属性的对象指向,如,等):

@property (readonly,nonatomic) NSString* name;
Run Code Online (Sandbox Code Playgroud)

我读到这里 关于ARC只读@property问题,离开关strong/ weak不实际编译除非你指定了后备变量时,你@synthesize的财产; 我恰巧正在指定这样的支持ivar:

@synthesize name = _name;
Run Code Online (Sandbox Code Playgroud)

现在我明白变量的默认'生命周期限定符'很强,从这里开始:http://developer.apple.com/library/ios/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html#//apple_ref/DOC/UID/TP40011226-CH1-SW4

所以简而言之 - 我间接地定义了我的财产,(readonly,nonatomic,strong)因为_nameivar被隐含地声明为__strong.

我有几个问题:

  1. 是否strong使用正确的终身限定符?我认为它是,否则支持我的对象NSString*将不会被拥有在任何地方,因此将自动释放(来自Java领域这是有道理的,因为默认情况下所有引用都很强).

  2. 在这种情况下是否还有其他修饰符,例如copyassign

  3. 声明财产是否(readonly,nonatomic,strong)消耗财产(readonly,nonatomic)的代码有任何区别?例如.并宣布它不关键字导致待存储的对象作为指针,其中属性将被存储在一个指针?strong__unsafe_unretainedstrong__strong

谢谢!

编辑

据我所知,以下适用于readonly属性:

  • 对于非NSObject*类型(int,float,void*等)使用(readonly, assign).
  • 对于对象指针,使用(readonly, strong)(readonly, copy)- 这些函数与readonly属性相同,但如果扩展/子类并将属性重新声明为,则可能需要复制语义readwrite.
  • 对于对象指针,(readonly, weak)只有在要在该属性中存储已经很弱的指针时才有意义(该指针必须在其他地方强,否则对象将被释放).

lna*_*ger 12

  1. strong如果你想保持一个强大的(拥有)引用你正指向的任何东西是正确的.通常,你确实想要强,但为了防止循环引用(特别是在父/子关系中,如果父指向子,子指向父,它们永远不会被释放)你有时需要使用弱引用.另外,如果你想保留一个你不拥有的对象的指针,但希望它只有存在才有效,那么你想要使用弱指针,因为当它被所有者释放时,你的指针将自动设置为,nil并且不会指向它不应该的内存.

  2. assign与标量值一起使用,是默认的setter. copy如果你想自动复制对象并将指针设置为副本而不是指向原始对象,这是有意义的.如果您有特殊需要(通常因为您不希望对象在您身上变异),这样做才有意义.

  3. 这表明__strong是默认的(因此你不需要指定它),你所提供的链接指向的变量,并不能声明的属性.声明的属性的默认值是assign如此,它肯定会有所作为.assign但是,如果你想要它,你是否指定它没有任何区别(除了要明确它是你想要的). 编辑:但是,正如雅克所指出的那样,LLVM 3.1正在改变,默认情况是从更改assignstrong.在这种情况下,无论您是否指定,它都没有区别strong,如果您愿意,可以将其遗漏.我个人认为拼出它是好的(特别是因为不同版本之间存在冲突)所以每个看代码的人都在同一页面上.其他人可能在这一点上不同意.:)

我建议在这里阅读Objective-C编程语言Declared Properties部分:.<document removed by Apple with no direct replacement>


Ken*_*ses 7

一个额外的点:性能可以从得到重新声明readonlyreadwrite.例如,一个子类可以使一个只读从超读写,类似于许多Cocoa类如何有新增的可变性的子类属性.同样,属性可以是公开只读的,但是类可以将其重新声明为读写以供类扩展中的内部使用.因此,当类设置自己的属性时,它可以利用合成的setter来正确执行内存管理并发出适当的Key-Value Observing更改通知.

目前的情况是,该属性的所有其他属性必须保持一致.可以想象编译器可以放宽这个要求.(有的认为这是一个错误.)无论如何,这是一个原因,申报readonly财产具有所有权的属性一样strong,copy或弱-这样它会在比赛readwrite重新声明别处.

关于你的问题3,你问的是所有权限定符是否影响调用getter的代码?不,它没有.