首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么时候我不能使用原子属性?

什么时候我不能使用原子属性?
EN

Stack Overflow用户
提问于 2015-11-19 04:04:09
回答 4查看 475关注 0票数 1

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

EN

回答 4

Stack Overflow用户

发布于 2015-11-19 04:29:00

声明属性atomic会使编译器生成阻止并发访问该属性的附加代码。这段额外的代码锁定一个信号量,然后获取或设置该属性,然后解锁该信号量。与设置或获取原始值或指针相比,锁定和解锁信号量的代价很高(尽管如果考虑到应用程序的整体流程,通常可以忽略不计)。

由于您在iOS下的大多数类,尤其是与UI相关的类,将在单线程环境中使用,因此删除atomic (即写入nonatomic__,因为默认情况下属性是atomic )是安全的,即使该操作相对便宜,您也不希望为不需要的东西买单。

票数 5
EN

Stack Overflow用户

发布于 2015-11-19 04:27:03

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

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

然而,这并不能保证线程的安全性。如果线程A调用getter,而线程B和C正在使用不同的值更新线程,那么线程A可以获得其中任何一个值,并且不能保证它将获得哪个值。

确切地说,许多场景允许非原子属性,如果不是大多数的话。尽管使用原子的额外开销可能可以忽略不计。简单地说,您的属性是在不同的线程上读取或设置的吗?如果不是,您很可能不需要将它们声明为原子的,但额外的开销可能甚至不明显。只是简单地将它们声明为原子并不能保证线程安全。

票数 1
EN

Stack Overflow用户

发布于 2015-11-19 04:28:08

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

什么?

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

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

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

代码语言:javascript
复制
NSString *fullName = [NSString stringWithFormat:@"%@ %@", person.firstName, person.lastName];

您知道,当您这样做时,其他线程可以更新属性。将属性设置为原子化没有任何帮助。如果在阅读第一个名字之后,但在阅读第二个名字之前更改了人员的姓氏,这是没有帮助的。如果在计算全名之后更改了人名,这是没有帮助的,因为这可能在下一个时刻无效。

你必须序列化操作,而不是属性访问。但是原子性只序列化访问。因此,如果至少有一个操作具有多个访问权限,则不会有任何帮助。99,999999373 %。

忘了属性原子性吧。这是没有意义的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33789316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档