preface

The keyword atomic and nonatomic are often used in iOS development when using @property to declare attributes

@property(nonatomic.strong)UIImage *icon;
@property(strong)UIImage *icon1;// Do not write the default atomic
Copy the code

The main difference between atomic and NonatomicD is that the system automatically generates getter/setter methods differently

  • The getter/setter methods automatically generated by the atomic system do the locking
  • Getter /setter methods automatically generated by the nonatomic system do not lock

atomic

The getter/setter methods generated by the system are locked. Note that this lock is only thread-safe for getter and setter access methods.

Because getter/setter methods are locked, the current operation is performed before another thread can read or write the property.

For example, thread 1 calls a setter for a property and is halfway through, and thread 2 calls its getter. After the setter is executed, thread 2 gets the full value of thread 1 after the getter is executed.

When several threads call the setter and getter methods of the same property at the same time, they will get a complete value, but the value can not be controlled.

Such as: So thread 1 calls the getter thread 2 calls the setter thread 3 calls the setter thread and these three threads start in parallel at the same time, thread 1 is going to get a value, but it’s not going to be controllable, it could be the original value before thread 2, thread 3 set, it could be the value of thread 2 set, it could be the value of thread 3 set

Are Atomic thread-safe?

No, A lot of articles talk about the difference between atomic and nonatomic and say that atomic is thread-safe, but this is not accurate. Atomic only locks getter/setter methods of properties, and this safety is only set/get If a thread is getting or setting and another thread is releasing at the same time, it may crash directly.

nonatomic

Getter /setter methods generated by the system are unsafe without locking threads, but faster when multiple threads access the same property at the same time, unexpected results can occur

Internal implementation

Let’s create a new nonatomic and an atomic variable and demonstrate their internal implementation in code

//interface
@property(nonatomic.strong)UIImage *icon;//nonatomic
@property(strong)UIImage *icon1;//atomic

Copy the code

Implementation of setter and getter methods for nonatomic objects


/ / MRC environment
//implementation
@synthesize icon = _icon;

//set- (void)setIcon:(UIImage *)icon
{
    if(_icon ! = icon) { [_icon release]; _icon = [iconretain]; }}//get- (UIImage *)icon
{
    return _icon;
}

Copy the code

Implementation of setter and getter methods for atomic objects

/ / MRC environment
//implementation
@synthesize icon1 = _icon1;

//set- (void)setIcon1:(UIImage *)icon1
{
    // Synchronize code blocks
    @synchronized (self) {
        
        if(_icon1 ! = icon1) { [_icon1 release]; _icon1 = [icon1retain]; }}}//get- (UIImage *)icon1
{
    UIImage *image = nil;
    // Synchronize code blocks
    @synchronized (self) {
        
        image = [[_icon1 retain] autorelease];
    }
    return image;
}

Copy the code

conclusion

  • Atomic only guarantees thread-safe access to getter and setter methods, but does not guarantee thread-safe access to the entire object, so in multithreaded programming, thread-safety needs to be handled by the developer himself.

  • About selection: Getters and setters generated by atomic systems guarantee the security of GET and set operations, but atomic is more expensive and slower than nonatomic. Therefore, on small devices such as iphones, if there is no communication between multiple threads, nonatomic is used A better choice

Code address :github.com/CoderZhuXH/…