Ios 什么时候我可以不使用原子属性?

Ios 什么时候我可以不使用原子属性?,ios,objective-c,Ios,Objective C,我知道原子答案和非原子答案是有区别的,但它们似乎都相当陈旧(2011年和更早),所以我希望得到最新的建议。我的理解是,非原子属性更快,但不是线程安全的。这是否意味着可以同时从多个线程访问的任何属性都应该是原子的?有没有条件可以使它成为非原子的?在决定一个属性是原子的还是非原子的过程中,还有什么其他的顾虑吗?没有其他顾虑。是的,可以在多个线程上访问的任何属性都应该是原子的,否则最终会产生意外的结果。没有其他问题。是的,可以在多个线程上访问的任何属性都应该是原子的,否则可能会导致意外的结果。将属性声

我知道原子答案和非原子答案是有区别的,但它们似乎都相当陈旧(2011年和更早),所以我希望得到最新的建议。我的理解是,非原子属性更快,但不是线程安全的。这是否意味着可以同时从多个线程访问的任何属性都应该是原子的?有没有条件可以使它成为非原子的?在决定一个属性是原子的还是非原子的过程中,还有什么其他的顾虑吗?

没有其他顾虑。是的,可以在多个线程上访问的任何属性都应该是原子的,否则最终会产生意外的结果。

没有其他问题。是的,可以在多个线程上访问的任何属性都应该是原子的,否则可能会导致意外的结果。

将属性声明为原子并不一定会使其成为线程安全的

原子是默认的,与非原子相比,它需要一些额外的开销。如果线程A正在完成该属性的getter的一半,而线程B更改了setter中的值,那么使用atomic将确保从getter返回一个可行的完整值。如果使用非原子,则不会生成额外的代码,因此非原子的速度更快

但是,这不能保证线程安全。如果线程A调用getter,并且线程B和C正在使用不同的值更新线程,那么线程A可能会得到其中一个值,并且不能保证它会得到哪个值


为了明确回答您的问题,许多场景都允许非原子属性,如果不是大多数的话。尽管使用原子的额外开销可能是可以忽略的。简单地说,您的属性是在不同的线程上读取还是设置的?如果不是,您很可能不需要将它们声明为原子的,但是额外的开销甚至可能不会被注意到。只是简单地将它们声明为原子并不能保证线程安全

将属性声明为原子属性并不一定会使其线程安全

原子是默认的,与非原子相比,它需要一些额外的开销。如果线程A正在完成该属性的getter的一半,而线程B更改了setter中的值,那么使用atomic将确保从getter返回一个可行的完整值。如果使用非原子,则不会生成额外的代码,因此非原子的速度更快

但是,这不能保证线程安全。如果线程A调用getter,并且线程B和C正在使用不同的值更新线程,那么线程A可能会得到其中一个值,并且不能保证它会得到哪个值


为了明确回答您的问题,许多场景都允许非原子属性,如果不是大多数的话。尽管使用原子的额外开销可能是可以忽略的。简单地说,您的属性是在不同的线程上读取还是设置的?如果不是,您很可能不需要将它们声明为原子的,但是额外的开销甚至可能不会被注意到。只是简单地将它们声明为原子并不能保证线程安全

在大多数情况下,属性在多线程环境中是否为原子属性并不重要

什么


在大多数情况下,属性在多线程环境中是否为原子属性并不重要

原因是,通过启用原子性使属性“线程安全”并不能使代码线程安全。要实现这一点,您需要做更多的工作,而这项工作通常会隐式地确保属性不会被并行访问

让我们举个例子:您有一个类
Person
,它的属性
firstName
lastName
都是
NSString*
。您只需添加两个名称,并用空格分隔,即可获得全名

NSString *fullName = [NSString stringWithFormat:@"%@ %@", person.firstName, person.lastName];
您知道,其他线程可以在您这样做时更新属性。使属性原子化没有任何帮助。如果在阅读第一个名字之后,但在阅读第二个名字之前,更改了人员的姓氏,则这没有帮助。如果在计算全名后更改了人员的姓名,则这没有帮助,因为这可能在下一刻无效

您必须序列化操作,而不是属性访问。但原子性只序列化访问。因此,如果至少有一个操作具有多个访问权限,那么它就没有帮助。99999999373%的病例


忘掉属性原子性吧。它没有意义。

在大多数情况下,属性在多线程环境中是否为原子属性并不重要

什么


在大多数情况下,属性在多线程环境中是否为原子属性并不重要

原因是,通过启用原子性使属性“线程安全”并不能使代码线程安全。要实现这一点,您需要做更多的工作,而这项工作通常会隐式地确保属性不会被并行访问

让我们举个例子:您有一个类
Person
,它的属性
firstName
lastName
都是
NSString*
。您只需添加两个名称,并用空格分隔,即可获得全名

NSString *fullName = [NSString stringWithFormat:@"%@ %@", person.firstName, person.lastName];
您知道,其他线程可以在您这样做时更新属性。使属性原子化没有任何帮助。如果在阅读第一个名字之后,但在阅读第二个名字之前,更改了人员的姓氏,则这没有帮助。如果在计算全名后更改了人员的姓名,则这没有帮助,因为这可能在下一刻无效

您必须序列化操作,而不是属性访问。但原子性只序列化访问。因此,如果至少有一个操作具有多个访问权限,那么它就没有帮助。99999999373%的病例

忘掉属性原子性吧。这是毫无意义的。

声明道具