如果我们使用GCD,我们是否需要声明属性为原子属性?

20 浏览
0 Comments

如果我们使用GCD,我们是否需要声明属性为原子属性?

Grand Central Dispatch是否关心原子性和非原子性关键字,还是我们必须无论如何指定原子性?

我知道在属性声明中使用原子性和非原子性关键字将生成不同的setter和getter方法,原子性将确保线程安全。

0
0 Comments

使用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

0