Iphone 螺纹安全固定/释放

Iphone 螺纹安全固定/释放,iphone,objective-c,ios,Iphone,Objective C,Ios,我有一个类可以从多个后台线程访问,可能是同时访问。我无法复制该类,因为重新创建(处理或内存方面)该类的内容可能会非常昂贵 在后台处理仍在进行并访问此属性时,也可能会替换此类的属性 目前我有定期的retain/RELEASE,但看起来(至少在iOS 4上)这些都不是线程安全的,因为即使它们是完美配对的,但显然会发生retainCount随机下降的情况,最终这个类被释放 我正在寻找有关如何使此类线程安全、允许并发访问属性以及允许在某个后台操作仍保留该属性的“早期版本”时修改该属性的建议。您是在谈论一

我有一个类可以从多个后台线程访问,可能是同时访问。我无法复制该类,因为重新创建(处理或内存方面)该类的内容可能会非常昂贵

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

目前我有定期的retain/RELEASE,但看起来(至少在iOS 4上)这些都不是线程安全的,因为即使它们是完美配对的,但显然会发生retainCount随机下降的情况,最终这个类被释放


我正在寻找有关如何使此类线程安全、允许并发访问属性以及允许在某个后台操作仍保留该属性的“早期版本”时修改该属性的建议。

您是在谈论一个类还是(我想)它的一个实例


无论如何,根据文档,保留和释放应该是线程安全的。因此,您可能在其他地方有一个bug(这可能取决于iOS 4,也可能不取决于iOS 4)。

保留/发布应该足以满足您的需要。如果您的对象是在两个线程之间访问的,那么它们需要通过一些中间地带进行通信来访问该对象,通常是同一个线程

例如:

//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,则需要重写这两个getter或setter,并使用您自己的锁定机制(@synchronize、NSLock等…)


保留和释放是原子的。自动释放是不可能的。按线程考虑保留;如果线程A持有retain(或retain/AUTORELASE),则线程A的引用将有效,直到该retain平衡(或AUTORELASE池耗尽)

Autorelease永远不能用作跨线程所有权转移原语


除此之外,如果没有更多的代码,很难说你的应用程序出了什么问题。

A@属性可以声明为“原子”,这是默认设置,因此可以从多线程安全访问它,保证结果的一致性:

@property (atomic, ...) NSString *someValue; // atomic is the default, thus optional
它保证在getter/setter的整个执行过程中,来自另一个线程的代码不会影响结果的一致性

id val = sharedObject.someValue;
val
中的结果将被保留并自动删除,因此无论其他线程发生什么情况,
val
将在当前运行循环的剩余时间内保持有效(在自动删除池耗尽之前)。获取
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];
    }
}

你保留/释放的是什么?
- (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];
    }
}