ARC的多线程自动释放问题?

时间:2013-05-20 02:32:26

标签: ios multithreading automatic-ref-counting atomicity

一类服务具有非原子属性,该属性在串行队列中设置。

@interface Service
@property (strong, nonatomic) NSDictionary *status;
@property (nonatomic) dispatch_queue_t queue;
...
@end

- (void)update:(NSDicationary *)paramDict {
    dispatch_async(self.queue, ^{
        ....
        self.status = updateDict;
    }
}


- (void)someMethod {
    NSDictionary *status = self.status;
}

objc_autorelease + 6调用getter时,应用程序崩溃,这似乎是运行时/ Clang / llvm调用。

崩溃日志还显示status属性刚刚设置在queue线程上。

由于访问者缺乏原子性,它是否崩溃了?如果是,那么getter如何以及为什么不能保留实例?自动释放池是否在合成的非原子设置器内耗尽?

我应该实现getter / setter方法,使用queue /互斥锁来保护它吗?

2 个答案:

答案 0 :(得分:1)

如果您不介意,请更改此代码。

非原子 - >原子

答案 1 :(得分:1)

虽然atomic可以解决多线程代码中基本数据类型的一些完整性问题,但通常不足以实现线程安全性。线程安全通常通过明智地使用锁或队列来实现。请参阅线程编程指南的Synchronization部分。或参见并发编程指南Eliminating Lock-Based Code,其中描述了使用队列代替同步锁。

假设您的队列是串行的,您可以使用以下构造使其成为线程安全的:

- (void)someMethod {
    dispatch_sync(self.queue, ^{

        NSDictionary *status = self.status;

        // do what you need to with status
    });
}

这样,您就可以有效地使用串行队列来同步对status字典的访问。

顺便说一下,如果您的队列是自定义并发,您可能还需要确保将dispatch_async中的paramDict替换为dispatch_barrier_async。如果您的队列是连续的,那么dispatch_async就可以了。

我建议您尝试使用您的队列或线程编程指南中描述的同步技术之一来同步对status的访问权。