我有一个物体,里面有一个strong
对对象的引用:
@property (nonatomic, strong) NSObject *thing;
在其他地方,我有一个传递对象引用的方法:
[thirdObject doSomething:secondObject.thing];
在一种情况下(一百万或十亿中),thirdObject 最终使用悬空指针,因为该对象被交换并且没有所有者。
我可以通过这样做来避免这种情况吗?这对 ARC 来说有什么不同吗?
NSObject *thing = secondObject.thing
[thirdObject doSomething:secondObject.thing];
如果不是,我该如何避免这种情况?
Edit:消息是“消息发送到已释放的实例 0xwhatever”
如果不应用某种线程安全性,则无法在多个线程上读取和写入属性。现在原则上,对于像字符串这样的简单对象,也许只需应用atomic
就足够了。看原子属性和非原子属性有什么区别?了解更多关于其具体作用的信息。
说实话,我真的不喜欢atomic
非常。我知道它的作用,但这似乎是一种获得你真正想要的东西的麻烦方法(而且通常最终会达不到你想要的)。这不是一个非常通用的解决方案;我无法自定义atomic
访问器“一点”(比如添加一个setNeedsDisplay
或类似)。
这就是为什么我喜欢基于队列的访问器。它们需要做更多的工作,但对解决很多问题都很有效。
@property (nonatomic, readwrite, strong) dispatch_queue_t thingQueue;
@property (nonatomic, strong) NSObject *thing;
- (id)init {
...
_thingQueue = dispatch_queue_create("...", DISPATCH_QUEUE_CONCURRENT);
...
}
- (NSObject *)thing {
__block NSObject *thing;
dispatch_sync(self.thingQueue, ^{
thing = _thing;
});
return thing;
}
- (void)setThing:(NSObject *)thing {
dispatch_barrier_async(self.thingQueue, ^{
_thing = thing;
});
}
我喜欢这个系统的地方在于它允许所有读者同时阅读。当作者尝试进行更新时,无论涉及多少读者,都保证不会挨饿。而且它总是很快返回。当值发生变化时,队列中还有一个明确的点,以便在写入器之前请求该值的读取器将始终获得旧值,而在写入器之后的读取器将始终获得新值,无论有多少争用在队列中。
关键是getter是同步的,所以它会一直等到能获取到值,而setter包含一个barrier。屏障意味着“当我运行时,不能从此队列中调度其他块”。因此,您有一堆并行运行的读取器块,然后设置器屏障出现并等待所有读取器完成。然后它单独运行,设置值,然后它后面的读者就可以再次并行运行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)