如果我们使用GCD,我们是否需要声明属性为原子属性?
使用atomic
是一种在多个线程中同步使用属性的方法。但是有很多机制可以同步多个线程的访问,而atomic
只是其中一种功能有限的方法。建议参考Threading Programming Guide中的Synchronization章节,了解更多的替代方法(甚至该指南也未讨论其他当代模式,如使用GCD串行队列和带有自定义并发队列的读写模式)。
总之,atomic
本身既不是必需的,也不足以确保线程安全。一般情况下,它在处理一些简单的基本数据类型(布尔值,NSInteger
)时具有一定的实用性,但在处理更复杂的逻辑或可变对象时是不足够的。
简而言之,不要认为在使用GCD时应该使用atomic
。事实上,如果使用了GCD,通常就不需要使用atomic
,而且atomic
会与GCD一起不必要地影响性能。因此,如果有一些属性被多个线程访问,应该进行同步,但选择使用哪种同步技术是根据具体情况的特定细节决定的,而GCD通常是更高效和更完整的解决方案。
在这个问题中,回答指出atomic
的性能优于GCD,是否有任何支持这一观点的统计数据?
这个问题比较的是GCD和atomic
,它们是不同的。但是可以进行简单的基准测试,例如stackoverflow.com/a/20939025/1271826。不过,atomic
和GCD之间的速度差异通常是不显著的,不会在实际应用中观察到。因此,atomic
可能会比GCD更快(尽管在真实应用中无法观察到),但更重要的是,在Objective-C中使用起来更简单。然而,GCD与atomic
的问题通常不是速度。事实上,在我们开发人员处理的99.9%的情况下,atomic
在结构上不足以提供所需的同步。它通常无法胜任工作。
总之,我尽可能使用Objective-C的atomic
,但实际上几乎从不使用。
我将一个NSString属性从'atomic'改为'nonatomic'后,崩溃率增加了,最后的回溯是-[NSString doubleValue],_NSScanDoubleFromString, _objc_msgSend
,在获取该属性的值时,有其他线程正在设置它,我不想使用atomic
,尽管队友喜欢使用它。
如果你在另一个线程改变属性的同时对它进行任何操作,你绝对必须对它进行同步。唯一的问题是atomic
是否足够。它可以在“一个线程读取并在另一个线程设置”场景中保护你,但如果你(或将来的其他程序员)使用了可变字符串,atomic
将不足够。顺便说一下,如果你遇到这样的问题,一定要使用线程安全检测工具进行调试。详见developer.apple.com/videos/play/wwdc2016/412。