Objective-C 声明的@property 属性(非原子、复制、强、弱)

Posted

技术标签:

【中文标题】Objective-C 声明的@property 属性(非原子、复制、强、弱)【英文标题】:Objective-C declared @property attributes (nonatomic, copy, strong, weak) 【发布时间】:2012-04-09 05:22:55 【问题描述】:

当我必须使用每个属性时,有人可以向我详细解释:nonatomiccopystrongweak 等等,对于声明的属性,并解释每个属性的作用?某种例子也会很棒。我正在使用 ARC。

【问题讨论】:

这里是答案***.com/a/32942413/1961064 rypress.com/tutorials/objective-c/properties 这说明了一切 【参考方案1】:

非原子

Nonatomic不会通过@synthesize 访问器生成线程安全例程。 atomic 将生成线程安全访问器,因此 atomic 变量是线程安全的(可以从多个线程访问而不会破坏数据)

复制

当对象可变时需要copy。如果您现在需要对象的值,并且您不希望该值反映对象的其他所有者所做的任何更改,请使用此选项。完成后您需要释放该对象,因为您保留了副本。

分配

Assigncopy 有点相反。当调用 assign 属性的 getter 时,它返回对实际数据的引用。通常,当您拥有原始类型(float、int、BOOL...)的属性时,您会使用此属性

保留

retain 当属性是指向在堆上分配的引用计数对象的指针时是必需的。分配应该类似于:

NSObject* obj = [[NSObject alloc] init]; // ref counted var

@synthesize 生成的 setter 将在对象被复制时添加一个引用计数,因此如果原始副本超出范围,底层对象不会自动销毁。

您需要在完成后释放该对象。 @propertys 使用retain 会增加引用计数并占用自动释放池中的内存。

strong 是保留属性的替代品,作为 Objective-C 自动引用计数 (ARC) 的一部分。在非 ARC 代码中,它只是保留的同义词。

这是一个了解 ios 5 的 strongweak 的好网站。 http://www.raywenderlich.com/5677/beginning-arc-in-ios-5-part-1

weak 类似于strong,只是它不会将引用计数增加 1。它不会成为该对象的所有者,而只是持有对它的引用。如果对象的引用计数降至 0,即使您可能仍然在此处指向它,它也会从内存中释放。

以上链接包含关于弱和强的良好信息。

【讨论】:

如果您只是在该类本身内部使用此 NSString,甚至不需要属性,您可以将其设为 iVar,如果您在另一个类中使用它,我会建议(强,复制)。 您缺少 Assign 属性。 nonatomic 表示它应该被多个线程同时访问。默认值为atomic,这使其成为线程安全的。 有点令人不安的是,经过这么长时间,非原子的定义仍然是错误的,并且类似于原子。我想知道在过去的五年里有多少人使用过它并产生了错误的印象。 @wcochran 说的是正确的。非原子意味着对指针的访问不是原子处理的,因此不是线程安全的。据我了解,非原子的好处是重量更轻。 除了@JohnBus​​hnell 的评论之外,此答案还有许多其他错误和不准确之处。它也没有很好地老化,所以有点历史。如果你想寻找这个问题的答案,去别处看看。【参考方案2】:

nonatomic 属性表示@synthesized 方法are not going to be generated threadsafe——但这比atomic 属性快得多,因为消除了额外的检查。

strong 与 ARC 一起使用,它基本上可以帮助您,不必担心对象的保留计数。完成后,ARC 会自动为您释放它。使用关键字strong 表示您拥有该对象。

weak 所有权意味着您不拥有它,它只是跟踪对象,直到分配给它的对象保持不变,一旦第二个对象被释放,它就失去了价值。例如。使用obj.a=objectB; 并且 a 具有弱属性,其值仅在 objectB 保留在内存中之前有效。

copy属性很好explained here

strong,weak,retain,copy,assign 是互斥的,因此您不能在一个对象上使用它们...阅读"Declared Properties " 部分

希望对你有所帮助...

【讨论】:

为什么强、弱、保留、复制、分配互斥 nonatomic 仅表示不应用排除。这并不意味着访问不是线程安全的。这是atomicnonatomic 没有捕获的实现细节。 @bbum 你能解释一下没有排除和线程不安全的区别吗? @AnkitSrivastava exclusion 是线程 A 阻止线程 B 沿着代码路径向下移动。如果该代码路径对于从多个线程执行是安全的,则不需要排除。 不是线程安全的 意味着如果 A 和 B 同时向下运行,代码路径可能会产生未定义的结果。也就是说,exclusion 可以用来使某些东西线程安全,但线程安全不需要独占——非并发——执行。【参考方案3】:

很好的答案! 我想更深入地澄清一件事是nonatomic/atomic。 用户应该明白这个属性——“原子性”只在属性的引用上传播,而不是在它的内容上。 IE。 atomic 将保证用户读取/设置指针的原子性,并且只保证指向属性的指针。 例如:

@interface MyClass: NSObject
@property (atomic, strong) NSDictionary *dict;
...

在这种情况下,可以保证指向dict 的指针将被不同的线程以原子方式读取/设置。 但是dict 本身(字典dict 指向)仍然是线程不安全,即对字典的所有读取/添加操作仍然是线程不安全的。

如果您需要线程安全的集合,您要么有糟糕的架构(更常见),要么有真正的需求(更罕见)。 如果这是“真正的要求” - 您应该找到经过良好测试的线程安全收集组件,或者准备好编写自己的测试和磨难。 后一种情况着眼于“无锁”、“无等待”范式。乍一看像是火箭科学,但与“通常的锁定”相比,它可以帮助您实现出色的性能。

【讨论】:

【参考方案4】:

这个链接有问题

http://clang.llvm.org/docs/AutomaticReferenceCounting.html#ownership.spelling.property

assign 意味着 __unsafe_unretained 所有权。

copy 意味着 __strong 所有权,以及 copy 的通常行为 setter 上的语义。

retain 意味着 __strong 所有权。

strong 意味着 __strong 所有权。

unsafe_unretained 意味着 __unsafe_unretained 所有权。

weak 意味着 __weak 所有权。

【讨论】:

Assign 属性不是仅用于 iVar 和值吗?那么为什么它不安全,为什么需要注意它是未保留的呢?

以上是关于Objective-C 声明的@property 属性(非原子、复制、强、弱)的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C中的@property和@synthesize用法

Objective-C 声明的@property 属性(非原子、复制、强、弱)

Objective-C中的@property和@synthesize用法

Objective-C中的@property和@synthesize用法

Objective-C中的@property

知识梳理Objective-C中的@property