3

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

@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;
}

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

并且崩溃日志还显示该status属性只是在queue线程上设置的。

它是否因为访问器中缺乏原子性而崩溃?如果是,吸气剂如何以及为什么未能保留实例?自动释放池是否在合成的非原子设置器中耗尽?

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

4

2 回答 2

1

如果您不介意,请像这样更改代码。

非原子的 -> 原子的

于 2013-05-20T02:47:47.903 回答
1

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

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

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

        NSDictionary *status = self.status;

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

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

顺便说一句,如果您的队列是自定义并发,您可能还需要确保将dispatch_asyncin替换paramDictdispatch_barrier_async. 如果您的队列是串行的,那dispatch_async很好。

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

于 2013-05-20T06:46:31.117 回答