1913

财产声明中的含义atomic和含义是什么?nonatomic

@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;

这三者在操作上有什么区别?

4

27 回答 27

1795

最后两个是相同的;“atomic”是默认行为(请注意,它实际上不是关键字;它仅通过缺少nonatomic--atomic被指定为最近版本的 llvm/clang 中的关键字)。

假设您正在 @synthesizing 方法实现,原子与非原子会更改生成的代码。如果您正在编写自己的 setter/getter,则 atomic/nonatomic/retain/assign/copy 只是建议性的。(注意:@synthesize 现在是 LLVM 最新版本中的默认行为。也不需要声明实例变量;它们也会自动合成,并且会_在其名称前添加一个前缀,以防止意外直接访问)。

使用“原子”,合成的 setter/getter 将确保始终从 getter 返回整个值或由 setter 设置,而不管任何其他线程上的 setter 活动。也就是说,如果线程 A 在 getter 的中间,而线程 B 调用 setter,则实际可行的值——很可能是一个自动释放的对象——将返回给 A 中的调用者。

nonatomic中,没有做出这样的保证。因此,nonatomic比“原子”要快得多。

“原子”不做的是对线程安全做出任何保证。如果线程 A 同时调用 getter,而线程 B 和 C 使用不同的值调用 setter,则线程 A 可能会返回三个值中的任何一个——在调用任何 setter 之前的那个值或传递给 setter 的值中的任何一个在 B 和 C 中。同样,对象可能以 B 或 C 中的值结束,无法判断。

确保数据完整性——多线程编程的主要挑战之一——是通过其他方式实现的。

添加到此:

atomicity当多个依赖属性在起作用时,单个属性的属性也不能保证线程安全。

考虑:

 @property(atomic, copy) NSString *firstName;
 @property(atomic, copy) NSString *lastName;
 @property(readonly, atomic, copy) NSString *fullName;

在这种情况下,线程 A 可以通过调用setFirstName:然后调用来重命名对象setLastName:。同时,线程 B 可能会fullName在线程 A 的两次调用之间进行调用,并将接收到新的名字和旧的姓氏。

为了解决这个问题,您需要一个事务模型。即某种其他类型的同步和/或排除允许一个人fullName在更新相关属性时排除访问。

于 2009-02-26T06:40:50.107 回答
363

这在 Apple 的文档中进行了解释,但以下是实际发生的一些示例。

请注意,没有“atomic”关键字,如果不指定“nonatomic”,则该属性是原子的,但显式指定“atomic”会导致错误。

如果您不指定“非原子”,则该属性是原子的,但如果您愿意,您仍然可以在最近的版本中明确指定“原子”。

//@property(nonatomic, retain) UITextField *userName;
//Generates roughly

- (UITextField *) userName {
    return userName;
}

- (void) setUserName:(UITextField *)userName_ {
    [userName_ retain];
    [userName release];
    userName = userName_;
}

现在,原子变体有点复杂:

//@property(retain) UITextField *userName;
//Generates roughly

- (UITextField *) userName {
    UITextField *retval = nil;
    @synchronized(self) {
        retval = [[userName retain] autorelease];
    }
    return retval;
}

- (void) setUserName:(UITextField *)userName_ {
    @synchronized(self) {
      [userName_ retain];
      [userName release];
      userName = userName_;
    }
}

基本上,原子版本必须锁定以保证线程安全,并且还会增加对象上的引用计数(以及自动释放计数以平衡它),以便保证调用者的对象存在,否则存在如果另一个线程正在设置该值,则可能是一种竞争条件,导致 ref 计数下降到 0。

实际上,这些事物的工作方式有很多不同的变体,具体取决于属性是标量值还是对象,以及保留、复制、只读、非原子等如何交互。一般来说,属性合成器只知道如何为所有组合做“正确的事情”。

于 2009-02-26T06:24:01.427 回答
174

原子

  • 是默认行为
  • 将确保当前进程由 CPU 完成,然后另一个进程访问该变量
  • 速度不快,因为它确保过程完全完成

非原子

  • 不是默认行为
  • 更快(对于合成代码,即对于使用@property 和@synthesize 创建的变量)
  • 不是线程安全的
  • 当两个不同的进程同时访问同一个变量时,可能会导致意外行为
于 2012-05-25T10:56:12.417 回答
141

了解差异的最佳方法是使用以下示例。

假设有一个名为“name”的原子字符串属性,如果你[self setName:@"A"]从线程 A 调用[self setName:@"B"],从线程 B 调用[self name],从线程 C 调用,那么不同线程上的所有操作都将串行执行,这意味着如果一个线程正在执行一个 setter或 getter,然后其他线程将等待。

这使得属性“name”读/写安全,但如果另一个线程 D[name release]同时调用,则此操作可能会产生崩溃,因为这里不涉及 setter/getter 调用。这意味着一个对象是读/写安全的(ATOMIC),但不是线程安全的,因为另一个线程可以同时向对象发送任何类型的消息。开发人员应确保此类对象的线程安全。

如果属性“name”是非原子的,那么上面示例中的所有线程 - A、B、C 和 D 将同时执行,产生任何不可预知的结果。在原子的情况下,A、B 或 C 中的任何一个将首先执行,但 D 仍然可以并行执行。

于 2012-01-31T18:36:08.980 回答
119

这个问题的其他优秀答案已经很好地定义了语法和语义。由于执行性能都不是很详细,所以我将添加我的答案。

这3个之间的功能区别是什么?

我一直认为 atomic 作为默认值非常好奇。在我们工作的抽象级别,使用类的原子属性作为实现 100% 线程安全的工具是一种极端情况。对于真正正确的多线程程序,程序员的干预几乎肯定是必需的。同时,性能特征和执行还没有深入详细说明。多年来编写了一些大量多线程程序,我一直在声明我的属性,nonatomic因为原子对于任何目的都不明智。在讨论原子和非原子属性的细节这个问题时,我做了一些分析,遇到了一些奇怪的结果。

执行

行。我想澄清的第一件事是锁定实现是实现定义和抽象的。路易斯@synchronized(self)在他的例子中使用了——我认为这是一个常见的混淆来源。该实现实际上并未使用@synchronized(self); 它使用对象级自旋锁。Louis 的插图非常适合使用我们都熟悉的结构进行高级插图,但重要的是要知道它不使用@synchronized(self).

另一个区别是原子属性将在 getter 中保留/释放您的对象。

表现

这是有趣的部分:在无争议(例如单线程)情况下使用原子属性访问的性能在某些情况下可能非常快。在不太理想的情况下,使用原子访问的开销可能是nonatomic. 而使用 7 个线程的Contested案例对于三字节结构(2.2 GHz Core i7 Quad Core,x86_64)慢了 44 倍。三字节结构是一个非常慢的属性的例子。

有趣的旁注:三字节结构的用户定义访问器比综合原子访问器快 52 倍;或合成非原子访问器速度的 84%。

有争议的案件中的对象也可以超过 50 次。

由于实施中的优化和变化的数量,很难在这些环境中衡量现实世界的影响。您可能经常听到类似“相信它,除非您分析并发现它是一个问题”之类的话。由于抽象级别,实际上很难衡量实际影响。从配置文件中收集实际成本可能非常耗时,并且由于抽象,非常不准确。同样,ARC 与 MRC 可以产生很大的不同。

因此,让我们退后一步,关注属性访问的实现,我们将包括常见的嫌疑人,例如,并检查在无争议的情况下对getterobjc_msgSend的许多调用的一些真实世界的高级结果(以秒为单位的值):NSString

  • MRC | 非原子| 手动实现的吸气剂:2
  • MRC | 非原子| 合成吸气剂:7
  • MRC | 原子| 合成吸气剂:47
  • 弧 | 非原子| 合成吸气剂:38(注意:ARC 在此处添加参考计数循环)
  • 弧 | 原子| 合成吸气剂:47

正如您可能已经猜到的那样,引用计数活动/循环是原子和 ARC 下的重要贡献者。您还会在有争议的案件中看到更大的差异。

虽然我很关注性能,但我还是说语义优先!. 同时,对于许多项目来说,性能是一个低优先级。但是,了解您使用的技术的执行细节和成本当然不会受到伤害。您应该根据自己的需要、目的和能力使用正确的技术。希望这将为您节省几个小时的比较时间,并帮助您在设计程序时做出更明智的决定。

于 2012-08-18T09:47:48.567 回答
96

原子 = 线程安全

非原子= 没有线程安全

线程安全:

如果实例变量在从多个线程访问时行为正确,则无论运行时环境对这些线程执行的调度或交错如何,并且调用代码部分没有额外的同步或其他协调,实例变量都是线程安全的。

在我们的上下文中:

如果一个线程更改了实例的值,则更改后的值可供所有线程使用,并且一次只有一个线程可以更改该值。

在哪里使用atomic

如果要在多线程环境中访问实例变量。

含义atomic

没有那么快,nonatomic因为nonatomic从运行时不需要任何看门狗工作。

在哪里使用nonatomic

如果实例变量不会被多个线程更改,则可以使用它。它提高了性能。

于 2013-07-10T13:07:39.873 回答
75

在阅读了这么多文章、Stack Overflow 帖子并制作了检查变量属性属性的演示应用程序后,我决定将所有属性信息放在一起:

  1. atomic // 默认
  2. nonatomic
  3. strong = retain // 默认
  4. weak = unsafe_unretained
  5. retain
  6. assign // 默认
  7. unsafe_unretained
  8. copy
  9. readonly
  10. readwrite // 默认

iOS 中的变量属性属性或修饰符一文中,您可以找到上述所有属性,这肯定会对您有所帮助。

  1. atomic

    • atomic意味着只有一个线程访问变量(静态类型)。
    • atomic是线程安全的。
    • 但是性能很慢
    • atomic是默认行为
    • 非垃圾收集环境中的原子访问器(即使用保留/释放/自动释放时)将使用锁来确保另一个线程不会干扰正确设置/获取值。
    • 它实际上不是关键字。

    例子:

        @property (retain) NSString *name;
    
        @synthesize name;
    
  2. nonatomic

    • nonatomic表示多线程访问变量(动态类型)。
    • nonatomic是线程不安全的。
    • 但它的性能很快
    • nonatomic不是默认行为。我们需要nonatomic在属性属性中添加关键字。
    • 当两个不同的进程(线程)同时访问同一个变量时,可能会导致意外行为。

    例子:

        @property (nonatomic, retain) NSString *name;
    
        @synthesize name;
    
于 2013-03-21T07:10:56.293 回答
70

我在这里找到了对原子和非原子属性的很好解释。以下是来自相同的一些相关文本:

“原子”意味着它不能被分解。在操作系统/编程术语中,原子函数调用是不能被中断的——必须执行整个函数,并且在完成之前不会通过操作系统通常的上下文切换将其从 CPU 中换出。以防万一您不知道:由于 CPU 一次只能做一件事,因此操作系统会在很小的时间片内轮换对所有正在运行的进程的 CPU 访问,以产生错觉的多任务处理。CPU 调度程序可以(并且确实)在进程执行的任何时候中断进程——即使是在函数调用中间。因此,对于像更新共享计数器变量这样的操作,其中两个进程可能会尝试同时更新变量,它们必须“原子地”执行,即,每个更新操作必须全部完成,然后任何其他进程才能交换到中央处理器。

所以我猜想在这种情况下原子意味着属性读取器方法不能被中断 - 实际上意味着方法读取的变量不能在中途改变它们的值,因为其他一些线程/调用/函数得到换到CPU上。

因为atomic变量不能被中断,所以它们包含的值在任何时候都是(线程锁)保证是未损坏的,尽管确保这个线程锁会使访问它们变慢。non-atomic另一方面,变量不做这样的保证,但确实提供了更快访问的奢侈。总而言之,non-atomic当您知道多个线程不会同时访问您的变量并加快速度时,请继续。

于 2012-02-24T05:17:25.370 回答
60

原子:

原子保证对属性的访问将以原子方式执行。例如,它总是返回一个完全初始化的对象,一个线程上的任何属性的获取/设置必须在另一个线程访问它之前完成。

如果您想象以下函数同时发生在两个线程上,您就会明白为什么结果不会很漂亮。

-(void) setName:(NSString*)string
{
  if (name)
  {
    [name release]; 
    // what happens if the second thread jumps in now !?
    // name may be deleted, but our 'name' variable is still set!
    name = nil;
  }

  ...
}

优点: 每次都返回完全初始化的对象,使其成为多线程情况下的最佳选择。

缺点: 性能下降,执行速度稍慢

非原子:

与 Atomic 不同,它不能确保每次都返回完全初始化的对象。

优点: 执行速度极快。

缺点: 在多线程的情况下垃圾值的机会。

于 2009-02-26T02:41:49.930 回答
52

首先是最简单的答案:您的后两个示例之间没有区别。默认情况下,属性访问器是原子的。

非垃圾收集环境中的原子访问器(即使用保留/释放/自动释放时)将使用锁来确保另一个线程不会干扰正确设置/获取值。

有关更多信息以及创建多线程应用程序时的其他注意事项,请参阅 Apple 的 Objective-C 2.0 文档的“性能和线程”部分。

于 2009-02-26T02:56:47.210 回答
31

原子意味着只有一个线程访问变量(静态类型)。Atomic 是线程安全的,但速度很慢。

非原子意味着多个线程访问变量(动态类型)。非原子是线程不安全的,但它很快。

于 2012-11-22T11:20:22.197 回答
15

Atomic 是线程安全的,它很,并且可以很好地保证(不保证)无论有多少线程尝试访问同一区域,都只提供锁定的值。使用 atomic 时,在此函数内编写的一段代码成为临界区的一部分,一次只能执行一个线程。

它只保证线程安全;它不保证这一点。我的意思是您为您的汽车聘请了一位专业的司机,但这并不能保证汽车不会发生事故。然而,概率仍然微乎其微。

原子的 - 它不能被分解,所以结果是预期的。使用非原子 - 当另一个线程访问内存区域时,它可以修改它,所以结果是意想不到的。

代码对话:

Atomic 使属性线程的 getter 和 setter 是安全的。例如,如果你写过:

self.myProperty = value;

是线程安全的。

[myArray addObject:@"Abc"] 

不是线程安全的。

于 2015-07-07T09:56:10.080 回答
13

原子(默认)

Atomic 是默认值:如果您不键入任何内容,则您的属性是原子的。保证原子属性,如果您尝试从中读取,您将返回一个有效值。它不保证该值可能是什么,但您将获得良好的数据,而不仅仅是垃圾内存。这允许您做的是,如果您有多个线程或多个进程指向一个变量,则一个线程可以读取而另一个线程可以写入。如果它们同时命中,则保证读取器线程获得以下两个值之一:更改之前或更改之后。atomic 没有为您提供任何关于您可能获得哪些值的保证。Atomic 通常与线程安全混淆,这是不正确的。您需要以其他方式保证您的线程安全。

非原子的

另一方面,正如你可能猜到的那样,非原子只是意味着“不要做那些原子的事情”。你失去的是保证你总能拿回一些东西。如果您尝试在写入过程中读取,则可能会取回垃圾数据。但是,另一方面,你走得更快一点。因为原子属性必须做一些魔术来保证你会得到一个值,所以它们有点慢。如果它是您经常访问的属性,您可能需要下拉到非原子以确保您不会受到速度损失。

在此处查看更多信息:https ://realm.io/news/tmi-objective-c-property-attributes/

于 2016-07-23T06:34:02.200 回答
12

没有这样的关键字“原子”

@property(atomic, retain) UITextField *userName;

我们可以像上面一样使用

@property(retain) UITextField *userName;

如果我使用 @property(atomic,retain)NSString *myString ,请参阅 Stack Overflow 问题。

于 2011-11-08T05:41:12.423 回答
11

默认值为,这atomic意味着无论何时使用该属性都会降低性能,但它是线程安全的。Objective-C 所做的是设置一个锁,因此只有实际线程可以访问该变量,只要执行了 setter/getter。

带有 ivar _internal 的属性的 MRC 示例:

[_internal lock]; //lock
id result = [[value retain] autorelease];
[_internal unlock];
return result;

所以最后两个是相同的:

@property(atomic, retain) UITextField *userName;

@property(retain) UITextField *userName; // defaults to atomic

另一方面,不会nonatomic向您的代码添加任何内容。因此,如果您自己编写安全机制,则只有线程安全。

@property(nonatomic, retain) UITextField *userName;

关键字根本不必写为第一个属性属性。

不要忘记,这并不意味着属性作为一个整体是线程安全的。只有setter/getter的方法调用是。但是,如果您使用一个 setter,然后同时使用一个带有 2 个不同线程的 getter,它也可能被破坏!

于 2013-09-27T09:43:38.620 回答
10
  • -Atomic 意味着只有一个线程访问变量(静态类型)。
  • -Atomic 是线程安全的。
  • - 但它的性能很慢

如何申报:

由于 atomic 是默认的,所以,

@property (retain) NSString *name;

AND 在实现文件中

self.name = @"sourov";

假设与三个属性相关的任务是

 @property (retain) NSString *name;
 @property (retain) NSString *A;
 @property (retain) NSString *B;
 self.name = @"sourov";

所有属性并行工作(如异步)。

如果您从线程A调用“名称” ,

同时,如果你打电话

[self setName:@"Datta"]

从线程B

现在如果 *name 属性是非原子的,那么

  • 它将为 A 返回值“Datta”
  • 它将为 B 返回值“Datta”

这就是为什么非原子被称为线程不安全的原因但是由于并行执行,它的性能很快

现在如果 *name 属性是原子的

  • 它将确保 A 的值“Sourov”
  • 然后它将为B返回值“Datta”

这就是为什么原子被称为线程安全这就是为什么它被称为读写安全

这种情况下的操作将连续执行。 并且性能缓慢

- 非原子意味着多线程访问变量(动态类型)。

- 非原子是线程不安全的。

- 但它的性能很快

-Nonatomic 不是默认行为,我们需要在属性属性中添加 nonatomic 关键字。

For In Swift 确认 Swift 属性在 ObjC 意义上是非原子的。一个原因是您考虑每个属性的原子性是否足以满足您的需求。

参考:https ://forums.developer.apple.com/thread/25642

更多信息请访问网站 http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html

于 2016-12-13T03:27:21.787 回答
9

如果您在多线程代码中使用您的属性,那么您将能够看到非原子属性和原子属性之间的区别。非原子比原子更快,原子是线程安全的,而不是非原子的。

Vijayendra Tripathi 已经给出了一个多线程环境的例子。

于 2014-08-13T11:57:09.213 回答
9

开始之前:您必须知道内存中的每个对象都需要从内存中释放,以便新的写入器发生。你不能像在纸上那样简单地写在上面。您必须先擦除(dealloc)它,然后才能在其上写入。如果此时擦除完成(或一半完成)并且尚未写入任何内容(或写入一半)并且您尝试阅读它可能会非常有问题!原子和非原子可帮助您以不同的方式处理此问题。

首先阅读这个问题,然后阅读Bbum 的答案。另外,然后阅读我的总结。


atomic将永远保证

  • 如果两个不同的人想同时读写,你的论文就不会烧毁了!--> 即使在竞态条件下,您的应用程序也永远不会崩溃。
  • 如果一个人正在尝试写并且只写了8个字母中的4个,那么中间没有可以阅读,只有当所有8个字母都写完才能阅读-->不会发生read(get) '一个仍在写入的线程',即如果有8个字节到要写入的字节,并且只写入了4个字节——到那个时候,你是不允许从中读取的。但是因为我说它不会崩溃,所以它会从自动释放对象的值中读取。
  • 如果写作之前你已经擦除了之前写在纸上的内容,然后有人想阅读,你仍然可以阅读。如何?您将从类似于 Mac OS 垃圾箱的内容中读取内容(因为垃圾箱尚未 100% 擦除......它处于不确定状态)---> 如果 ThreadA 在 ThreadB 已被释放写入时读取,您将得到来自 ThreadB 最终完全写入的值或从自动释放池中获取的值。

保留计数是 Objective-C 中管理内存的方式。创建对象时,它的保留计数为 1。当您向对象发送保留消息时,其保留计数加 1。当您向对象发送释放消息时,其保留计数减 1。当您向一个对象发送一条自动释放消息,它的保留计数在将来的某个阶段减 1。如果一个对象的保留计数减少到 0,它就会被释放。

  • Atomic保证线程安全,尽管它对于实现线程安全很有用。线程安全与您编写代码的方式/正在读取/写入的线程队列有关。它只保证不可崩溃的多线程。

什么?!多线程和线程安全有区别吗?

是的。多线程意味着:多个线程可以同时读取一个共享的数据并且我们不会崩溃,但它不能保证您不是从非自动释放的值中读取。使用线程安全,可以保证您阅读的内容不会自动发布。默认情况下我们不将所有内容都设为原子的原因是,存在性能成本,并且对于大多数事情来说并不真正需要线程安全。我们代码的一些部分需要它,对于这几个部分,我们需要使用锁、互斥锁或同步以线程安全的方式编写代码。


nonatomic

  • 因为没有像 Mac OS 垃圾箱这样的东西,所以没有人关心你是否总是得到一个值(<-- 这可能会导致崩溃),也没有人关心是否有人试图在你的写作中读到一半(尽管在内存中写一半与在纸上写一半有很大不同,在内存上它可能会给你一个疯狂的愚蠢价值,而在纸上你只能看到一半已经写的东西)--> 不保证不会崩溃,因为它不使用自动释放机制。
  • 不保证读取完整的书面值!
  • 比原子更快

总体而言,它们在两个方面有所不同:

  • 是否因为有或没有自动释放池而崩溃。

  • 允许在“尚未完成写入或空值”的中间读取,或者不允许并且仅在值完全写入时才允许读取。

于 2016-04-28T16:18:23.940 回答
9

原子性 原子性(默认)

Atomic 是默认值:如果您不键入任何内容,则您的属性是原子的。保证原子属性,如果您尝试从中读取,您将返回一个有效值。它不保证该值可能是什么,但您将获得良好的数据,而不仅仅是垃圾内存。这允许您做的是,如果您有多个线程或多个进程指向一个变量,则一个线程可以读取而另一个线程可以写入。如果它们同时命中,则保证读取器线程获得以下两个值之一:更改之前或更改之后。atomic 没有为您提供任何关于您可能获得哪些值的保证。Atomic 通常与线程安全混淆,这是不正确的。您需要以其他方式保证您的线程安全。

非原子的

另一方面,正如你可能猜到的那样,非原子只是意味着“不要做那些原子的事情”。你失去的是保证你总能拿回一些东西。如果您尝试在写入过程中读取,则可能会取回垃圾数据。但是,另一方面,你走得更快一点。因为原子属性必须做一些魔术来保证你会得到一个值,所以它们有点慢。如果它是您经常访问的属性,您可能需要下拉到非原子以确保您不会受到速度损失。使用权

礼貌https://academy.realm.io/posts/tmi-objective-c-property-attributes/

原子性属性(原子和非原子)没有反映在相应的 Swift 属性声明中,但是当从 Swift 访问导入的属性时,Objective-C 实现的原子性保证仍然有效。

所以——如果你在 Objective-C 中定义一个原子属性,它在被 Swift 使用时仍然是原子的。

礼貌 https://medium.com/@YogevSitton/atomic-vs-non-atomic-properties-crash-course-d11c23f4366c

于 2019-01-29T06:12:16.930 回答
5

atomic 属性确保保留完全初始化的值,而不管有多少线程在其上执行 getter 和 setter。

非原子属性指定合成访问器直接设置或返回一个值,不保证如果从不同线程同时访问相同的值会发生什么。

于 2015-10-23T15:41:25.653 回答
3

原子意味着一次只有一个线程可以访问变量(静态类型)。Atomic 是线程安全的,但速度很慢。

非原子意味着多个线程可以同时访问变量(动态类型)。非原子是线程不安全的,但它很快。

于 2016-02-01T08:27:02.147 回答
1

事实是他们使用自旋锁来实现原子属性。代码如下:

 static inline void reallySetProperty(id self, SEL _cmd, id newValue, 
      ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy) 
    {
        id oldValue;
        id *slot = (id*) ((char*)self + offset);

        if (copy) {
            newValue = [newValue copyWithZone:NULL];
        } else if (mutableCopy) {
            newValue = [newValue mutableCopyWithZone:NULL];
        } else {
            if (*slot == newValue) return;
            newValue = objc_retain(newValue);
        }

        if (!atomic) {
            oldValue = *slot;
            *slot = newValue;
        } else {
            spin_lock_t *slotlock = &PropertyLocks[GOODHASH(slot)];
            _spin_lock(slotlock);
            oldValue = *slot;
            *slot = newValue;        
            _spin_unlock(slotlock);
        }

        objc_release(oldValue);
    }
于 2016-12-09T04:58:38.057 回答
1

在一行中:

Atomic是线程安全的。Nonatomic是线程不安全的。

于 2021-07-03T07:48:01.220 回答
0

如果您使用原子,则意味着线程将是安全且只读的。如果你使用的是非原子的,这意味着多个线程访问变量并且是线程不安全的,但是它执行得很快,做了一个读写操作;这是一种动态类型。

于 2016-02-13T13:34:35.600 回答
-1

原子:通过使用 NSLOCK 锁定线程来确保线程安全。

非原子:不确保线程安全,因为没有线程锁定机制。

于 2016-06-29T08:56:11.037 回答
-1

为了简化整个混淆,让我们了解互斥锁。

互斥锁,顾名思义,锁定对象的可变性。因此,如果对象被一个类访问,则没有其他类可以访问同一个对象。

在 iOS 中,@sychronise还提供了互斥锁。现在它以 FIFO 模式服务,并确保流不受共享同一实例的两个类的影响。但是,如果任务在主线程上,请避免使用原子属性访问对象,因为它可能会占用您的 UI 并降低性能。

于 2016-09-23T18:41:26.640 回答
-2

原子属性:- 当分配有原子属性的变量意味着它只有一个线程访问并且它将是线程安全的并且从性能角度来看会很慢时,将具有默认行为。

非原子属性:-当分配有原子属性的变量意味着它具有多线程访问并且它不是线程安全的并且从性能角度来看会很快时,将具有默认行为并且当两个不同的线程想要同时访问变量时它会产生意想不到的结果。

于 2018-08-04T11:26:43.123 回答