When we create @property, we use atomic and nonatomic, but what’s the difference

atomic

  • Is the default
  • Set and GET operations on the same object are performed sequentially
  • It’s slow because you have to make sure the operation is complete
  • Thread-safe, consuming a lot of system resources to lock properties

Using atomic does not guarantee absolute thread-safety. For thread-safe operations, more advanced methods such as NSSpinLock and @syncronized are needed

nonatomic

  • Not by default
  • faster
  • If two threads access the same property, unexpected results can occur
  • Non-thread-safe, suitable for mobile devices with small memory

  • Without addingatomicornonatomicThe default isatomic
  • Setter/getter methods

At ordinary times in his writing the setter and getter methods, atomic/nonatomic/retain/assign function tip/copy these keywords, write not write all the same.

Getters/setters generated by the atomic system guarantee the integrity of get and set operations from other threads. For example, if thread A’s getter is halfway through, thread B calls the setter: thread A’s getter still gets an intact object.

nonatomic

There is no guarantee of getter integrity, but it runs faster than atomic


Assuming there is an atomic attribute “name”, if thread A calls [self setName:@”A”], thread B calls [self setName:@”B”], thread C calls [self name], Then all the operations on these different threads will be executed sequentially — that is, if one thread is executing the getter/setter, the other threads will have to wait. Therefore, the attribute name is read/write safe.

However, if another thread D were calling [name Release] at the same time, it might crash because release is not limited by getter/setter operations. That is, this property is read/write safe, but not thread-safe, because other threads can do things other than read and write. Thread safety needs to be ensured by the developers themselves.

If the name attribute is nonatomic, then all threads A, B, C, and D in the above example can execute simultaneously, potentially leading to unexpected results. If atomic, then A, B, and C will be serial, while D will remain parallel.


In simple terms, atomic will add a lock that is basically thread-safe (but not thread-safe), and the reference count will be +1 to assure the caller that the object will always exist. If you don’t, if another thread calls the setter, a thread race may occur, causing the reference count to drop to zero and the original object to be released.

@property(nonatomic, retain) UITextField *userName;
// The system generates the following code:

- (UITextField *) userName {
    return userName;
}

- (void) setUserName:(UITextField *)userName_ {
    [userName_ retain];
    [userName release];
    userName = userName_;
}
Copy the code
@property(retain) UITextField *userName;
// The system generates the following code:

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

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