我有一个可以同时从多个后台线程访问的类。我无法复制该类,因为它的内容可能很难重新创建(处理或内存方式)。
当后台处理仍在进行并访问此属性时,也可能替换此类的属性。
目前我有定期保留/发布,但似乎是这种情况(至少在iOS 4上)这些不是线程安全的,因为即使它们是完美配对,显然会发生retainCount随机丢弃并最终class被取消分配。
我正在寻找有关如何使此类线程安全的建议,允许并发访问属性并允许修改属性,同时属性的“早期版本”仍由其中一个背景保留动作。
答案 0 :(得分:6)
保留和释放是原子的。自动释放不是。考虑保留为每线程;如果线程A持有保留(或保留/自动释放),则线程A的引用将有效,直到该保留被平衡(或自动释放池被耗尽)。
Autorelease可以永远不会用作跨线程所有权转移原语。
除此之外,很难说没有更多代码的应用程序出现了什么问题。
答案 1 :(得分:1)
你是在谈论一个课程还是(我想)一个实例?
无论如何,根据文档,保留和释放应该是线程安全的。所以你可能在其他地方有一个bug(可能或可能不依赖于iOS 4)。
答案 2 :(得分:0)
保留/释放应足以满足您的要求。如果你的对象是在两个线程之间访问的,那么他们需要通过一些中间接口来访问这个对象,通常这将是同一个线程。
示例:
//Thread 1 Object
//Setting thread 2's object will occur on the same thread so
//retains and releases will happen in order with no issue
thread2Object.atomicObject = self.atomicObject;
确保您的属性是原子的(线程安全)意味着不要在属性声明中放置非原子。如果您决定覆盖getter或setter,则需要覆盖它们并使用自己的锁定机制(@ synchronize,NSLock等)。
@propert(retain) NSObject *atomicObject;
答案 3 :(得分:0)
@property可以声明为'atomic',这是默认值,因此可以从多线程安全地访问它,保证结果的一致性:
@property (atomic, ...) NSString *someValue; // atomic is the default, thus optional
它保证在整个getter / setter的执行过程中,来自另一个线程的代码不会影响结果的一致性。
id val = sharedObject.someValue;
val
中的结果被保留并自动释放,因此无论其他线程发生什么,val
将在当前runloop循环的剩余时间内(在自动释放池耗尽之前)保持有效。获得val
后,无法保证sharedObject.someValue
将是相同的,因为另一个线程可以重新分配它。
示例,假设在后台线程上定期调用someMethod
,并取决于您的sharedObject
:
- (void)someMethod {
SomeObject *val = sharedObject.someValue;
// now, val will remain consistent,
// regardless of what happens to sharedObject.someValue
[val doSomething];
if (val.someInt > 50) {
[val doSomethingElse];
}
}