我是iOS开发的新手,从未处理过手动引用计数(保留,释放,自动释放)。因此,我对ARC的神奇表现并不了解。
我以为我理解了,直到有人询问我应该将哪种类型的所有权(weak
,strong
,assign
等)赋予指向对象的只读属性,例如:
@property (readonly,nonatomic) NSString* name;
我在这里读到
离开strong
/ weak
的{{3}}除非您在@synthesize
财产时指定支持变量,否则实际上不会编译;我恰好正在指定这样的支持ivar:
@synthesize name = _name;
现在我明白变量的默认'生命周期限定符'很强,从这里开始:Questions about a readonly @property in ARC
所以简而言之 - 我间接地将我的属性定义为(readonly,nonatomic,strong)
,因为_name
ivar被隐式声明为__strong
。
我有几个问题:
strong
是否使用正确的生命周期限定符?我认为它是,否则支持我的NSString*
的对象将不会被拥有在任何地方,因此将自动释放(来自Java领域这是有道理的,因为默认情况下所有引用都很强)。
在这种情况下是否有其他有意义的修饰符,例如copy
或assign
?
将属性声明为(readonly,nonatomic,strong)
和(readonly,nonatomic)
会对使用属性的代码产生任何影响吗?例如。在没有strong
关键字的情况下声明它会导致对象指针存储为__unsafe_unretained
,其中strong
属性将存储在__strong
指针中吗?
谢谢!
修改
据我所知,以下内容适用于只读属性:
(readonly, assign)
。(readonly, strong)
或(readonly, copy)
- 这些函数对于readonly属性的功能相同,但如果扩展/子类并将属性重新声明为readwrite
,则可能需要复制语义。 (readonly, weak)
只有在您要在该属性中存储已经很弱的指针时才有意义(该指针必须在其他位置强,否则该对象将被释放)。答案 0 :(得分:12)
strong
如果您希望保留对您所指向的任何内容的强大(拥有)引用,则使用正确。通常,你确实想要强,但为了防止循环引用(特别是在父/子关系中,如果父指向子,子指向父,它们永远不会被释放)你有时需要使用弱引用。另外,如果你想保留一个你不拥有的对象的指针,但希望它只有存在才有效,那么你想要使用一个弱指针,因为当它获得时由所有者解除分配后,您的指针将自动设置为nil
,并且不会指向不应存在的内存。
assign
与标量值一起使用,是默认的setter。如果您想自动复制对象并将指针设置为副本而不是指向原始对象,则copy
是有意义的。如果您有特殊需要(通常是因为您不希望对象在您身上发生变异),这样做才有意义。
您提供的链接显示__strong是默认值(因此您无需指定),指的是变量和不 声明的属性。声明属性的默认值为assign
,因此它肯定会有所作为。但是,如果你想要assign
,那么无论你是否指定它都没有区别(除了要明确它是你想要的)。
编辑:但是,正如Jacques指出的那样,LLVM 3.1正在发生变化,默认情况下 正在将 从assign
更改为{{ 1}}。在这种情况下,无论您是否指定strong
都没有区别,如果您愿意,可以将其删除。我个人认为拼出它是好的(特别是因为不同版本之间存在冲突)所以每个看代码的人都在同一页面上。其他人可能在这一点上不同意。 :)
我建议在这里阅读 Objective-C编程语言的声明的属性部分:strong
。
答案 1 :(得分:7)
还有一点:属性可以从readonly
重新声明为readwrite
。例如,子类可以从超类读写中创建只读属性,类似于有多少Cocoa类具有增加可变性的子类。同样,属性可以是公开只读的,但是类可以将其重新声明为读写以供类扩展中的内部使用。因此,当类设置自己的属性时,它可以利用合成的setter来正确执行内存管理并发出适当的Key-Value Observing更改通知。
目前的情况是,该属性的所有其他属性必须保持一致。可以想象编译器可以放宽这个要求。 (有些人认为这是一个错误。)无论如何,这是宣布具有readonly
,strong
或弱所有权属性的copy
属性的一个原因,以便它与{{{ 1}}重新声明其他地方。
关于您的问题3,您是否询问所有权限定符是否会影响调用getter的代码?不,它没有。
答案 2 :(得分:0)
这两行代码对我有用:
.h文件:
@property (nonatomic, readonly, copy) NSString *username;
.m文件:
@property (nonatomic, readwrite, copy) NSString *username;