When can I not use atomic properties?
我知道有关于原子答案和非原子答案的答案,但它们大多看起来相当古老(2011年和更早),所以我希望得到最新的建议。我的理解是,非原子属性更快,但线程不安全。这是否意味着可以同时从多个线程访问的任何属性都应该是原子的?有没有条件可以使它成为非原子的?在决定是使一个属性成为原子的还是非原子的过程中,还有什么其他的关注呢?
声明属性
由于大多数IOS下的类,特别是与UI相关的类,将在单线程环境中使用,因此可以安全地删除
在大多数情况下,属性在多线程环境中是否为原子属性并不重要。
什么?
在大多数情况下,属性在多线程环境中是否为原子属性并不重要。
这样做的原因是,通过打开原子性使属性"线程安全"不会使代码线程安全。要得到这个,您需要做更多的工作,而这个工作通常会隐式地确保属性不被并行访问。
让我们举个例子:有一个类
1 | NSString *fullName = [NSString stringWithFormat:@"%@ %@", person.firstName, person.lastName]; |
您知道其他线程可以在您执行此操作时更新属性。使属性具有原子性并没有任何帮助。如果人们的姓氏在读了名字之后,但在读了第二个名字之前发生了变化,这没有帮助。如果在计算全名后更改了人员的姓名,这没有帮助,因为这在下一刻可能无效。
您必须序列化操作,而不是属性访问。但是原子性只序列化访问。因此,如果至少有一个操作具有多个访问权限,那么它就没有帮助。所有病例的99999999 373%。
忘记属性原子性。这是毫无意义的。
将属性声明为原子属性不一定使其线程安全。
原子是默认的,与非原子相比,它需要一些额外的开销。如果线程A在该属性的getter的中途,而线程B更改了setter中的值,那么使用atomic将确保从getter返回一个可行的完整值。如果使用非原子,则不会生成额外的代码,因此非原子速度更快。
但是,这并不能保证螺纹安全。如果线程A调用getter,而线程B和C正在用不同的值更新线程,那么线程A可以获取任意一个值,并且不能保证它将获得哪个值。
为了具体地回答您的问题,许多场景都允许非原子属性,如果不是大多数的话。尽管使用原子的额外开销可能是可以忽略的。简单地说,您的属性是在不同的线程上读取还是设置的?如果不是,您很可能不需要将它们声明为原子的,但是额外的开销甚至可能不会被注意到。只是简单地将它们声明为原子并不保证线程安全。
没有其他问题。是的,可以在多个线程上访问的任何属性都应该是原子的,否则最终可能会得到意外的结果。