iOS记录

iOS中使用atomic就能保证安全了吗?

2021-08-19  本文已影响0人  希尔罗斯沃德_董

什么是atomic?

iOS 中属性修饰符有atomic 和 nonatomic ,atomic表示原子性,反之nonatomic是非原子性。所谓原子性,在这里就是保证属性的setter方法和getter方法操作的原子性。那么,是不是使用atomic就能保证线程安全了呢?

atomic修饰可变对象

没错,如果使用atomic修饰的是可变对象的话,是无法保证线程安全,就比如NSMutableArray,它可以insert、delete等操作,这些操作并不会通过setter方法,也就失去了atomic的保护范围。但是如果atomic修饰的是一普通对象就一定线程安全吗?

直接访问成员变量

要回答这个问题还得从setter和getter方说起,以setter方法为例假设这样一个属性 @property (atomic, strong) id object;他的setter方法(ARC下)应该是:

- (void)setObject:(id)object
{
  _object = object;
}

在底层他要实现原子操作,肯定需要加一些类似锁或者同步之类的操作,假设它的原子操作模型如下:

- (void)setObject:(id)object
{
        [lock lock];
        _object = object;
        [lock unlock];
}

这里在set方法进行赋值时进行加锁以保证线程安全。但是,如果我们并没有调用setter方法赋值,而是直接访问实例变量_object,它还是线程安全吗?就比如下面的代码:

- (void)test
{
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    for (int i = 0; i < 100000; i++) {
        dispatch_async(globalQueue, ^{
            [self update];
            NSLog(@"%@", @(i));
        });
    }
    [self update];
}

- (void)update
{
   _object = [[NSObject alloc] init];
}

这里的代码直接访问的是实例变量_object,并没有走set方法,显然是无法保证线程安全的。所以使用atomic是无法保证线程安全的,要保证线程安全显然还是要做更多细致的考虑。

上一篇下一篇

猜你喜欢

热点阅读