美文网首页程序员
nonatomic和atomic理论以及案例

nonatomic和atomic理论以及案例

作者: 小曼blog | 来源:发表于2020-06-18 16:50 被阅读0次

我们在声明属性的时候,往往在@property的括号中第一个就写上nonatomic,但是nonatomic是什么意思?又有什么作用呢?
我们在搜索nonatomic和atomic的时候,很多人都会给你相似的答案,却鲜少有人贴出代码来验证一下,我自认为是个笨拙的人,不自己验证一下总是不那么放心。
先看看理论上nonatomic和atomic的不同吧。
atomic的英文意思是原子的。


image.png

我们姑且称它为原子性吧。它的作用应该就是为了使得对象读写的时候更加安全而设立的。它们俩的最大的区别就在于系统生成的getter和setter方法不一样。我们来看看吧。

@property(atomic, strong)UIImage * icon1;
@property(nonatomic, strong)UIImage * icon2;

nonatomic对象setter和getter方法的实现

//mrc 环境
//implementation
@synthesize icon2 = _icon2;

//set
-(void)setIcon2:(UIImage *)icon2
{
    if(_icon2 != icon2)
    {
        [_icon2 release];
        _icon2 = [icon2 retain];
    }
}
//get
-(UIImage *)icon2
{
    return _icon2;
}

atomic对象setter和getter方法的实现

//mrc 环境
//implementation
@synthesize icon1 = _icon1;

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

扩展
@synchronized(对象)中的这个"对象"是什么,锁定它是为了什么? 这个对象可以是任意一个object,作用是以object的内存地址映射到系统维护的一个递归锁;当获得锁之后,其他线程想进入同一段代码时需要等待,其他线程想使用同一个object进行加锁时也需要等待。
@synchronized (self)这种写法会根据给定的对象,自动创建一个锁,并等待块中的代码执行完毕。执行到这段代码结尾处,锁就释放了。
我们现在明白了,atomic修饰的对象,在setter和getter方法中,都加了一个锁,也就是在存取的时候,只有当存取已经完成了,其他线程才能够访问这个对象,这样保证了这个对象在存取的时候是安全的。

我们用图示来表示:

image.png

如此看来,atomic还是能够保证存取的时候是安全的,那么它是线程安全的吗?不一定的。我们举个例子试试。
例:
一个对象name = “hello”,有三个异步线程A、B、C,A中取name的值,B、C改变name的值,那么最终,name的值为多少?A中取到的又是哪一个值呢?

//  Copyright © 2020 weiman. All rights reserved.

#import "ViewController.h"

@interface ViewController ()

@property(atomic,strong)NSString * name;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.name = @"hello";
    
    NSBlockOperation *blockA = [NSBlockOperation blockOperationWithBlock:^{
        
        NSLog(@"blockA- %@",[NSThread currentThread]);
        NSLog(@"blockA name = %@", self.name);
    }];
    NSBlockOperation *blockB = [NSBlockOperation blockOperationWithBlock:^{
          
        NSLog(@"blockB- %@",[NSThread currentThread]);
        self.name = @"小橘子";
       }];
    NSBlockOperation *blockC = [NSBlockOperation blockOperationWithBlock:^{
          
         NSLog(@"-blockC-%@",[NSThread currentThread]);
         self.name = @"小土豆";
       }];
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    queue.maxConcurrentOperationCount = 3;

    [queue addOperation:blockA];
    [queue addOperation:blockB];
    [queue addOperation:blockC];
    
}


@end

打印结果:

image.png image.png

多运行几次发现,打印结果并不固定,说明atomic并不能做到线程安全。因为线程安全还有读写之外的其他操作(比如:如果当一个线程正在get或set时,又有另一个线程同时在进行release操作,可能会直接crash)。
因为atomic的读写加锁操作,会使得性能降低,读写变得耗时,所以我们在声明属性的时候基本不会使用它。
说完了atomic,我们就知道我们常用的nonatomic的意思了,就是读写不加锁的操作。

总结
atomic:
1.系统默认的
2.读写安全的
3.线程不安全的
4.消耗性能的
nonatomic:
1.读写不安全
2.不消耗性能,快速读写

相关文章

  • nonatomic和atomic理论以及案例

    我们在声明属性的时候,往往在@property的括号中第一个就写上nonatomic,但是nonatomic是什么...

  • iOS atomic与nonatomic的区别以及各自功能

    一、atomic与nonatomic的区别! 首先,先介绍一下atomic和nonatomic 1.atomic使...

  • iOS 属性关键字(二)

    原子性 原子性就nonatomic和atomic两个关键字 atomic与nonatomic atomic是默认的...

  • iOS atomic & nonatomic的区别

    iOS atomic & nonatomic的区别 前言 atomic 和 nonatomic 用来决定编译器生成...

  • 关键字(@property属性)(I)

    nonatomic和atomic nonatomic:不使用同步锁,非原子性 atomic:使用同步锁,原子性 属...

  • nonatomic和atomic

    原子性(atomic):某操作具备整体性,也就是说,系统其他部分无法观察到其中间步骤所生成的临时结果,而只能看到操...

  • atomic 和 nonatomic

    解释就没必要的,网上、书上太多说明了,主要说说他们的区别,和一些容易理解错误的地方。 atomic并不是线程安全:...

  • nonatomic 和atomic

    两者的区别: 具备atomic特质会通过锁定机制来保持其操作的原子性,如果两个线程读写同一属性 那么无论何时,总能...

  • atomic和nonatomic

    atomic和nonatomic区别用来决定编译器生成的getter和setter是否为原子操作。atomic提供...

  • atomic和nonatomic

    常见场景 在定义 property 的时候,atomic和nonatomic有何区别? 答案:2,3行是一样的,不...

网友评论

    本文标题:nonatomic和atomic理论以及案例

    本文链接:https://www.haomeiwen.com/subject/rltuxktx.html