线程安全保留/释放

时间:2011-06-28 20:13:54

标签: iphone objective-c ios

我有一个可以同时从多个后台线程访问的类。我无法复制该类,因为它的内容可能很难重新创建(处理或内存方式)。

当后台处理仍在进行并访问此属性时,也可能替换此类的属性。

目前我有定期保留/发布,但似乎是这种情况(至少在iOS 4上)这些不是线程安全的,因为即使它们是完美配对,显然会发生retainCount随机丢弃并最终class被取消分配。

我正在寻找有关如何使此类线程安全的建议,允许并发访问属性并允许修改属性,同时属性的“早期版本”仍由其中一个背景保留动作。

4 个答案:

答案 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];
    }
}