【问题标题】:thread-safe retain/release线程安全的保留/释放
【发布时间】:2011-06-28 20:13:53
【问题描述】:

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

当后台处理仍在继续并访问该属性时,也有可能替换此类的属性。

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

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

【问题讨论】:

  • 你保留/释放什么?

标签: iphone objective-c ios


【解决方案1】:

保留和释放是原子的。自动释放不是。将保留视为每个线程;如果线程 A 持有一个保留(或保留/自动释放),那么线程 A 的引用将一直有效,直到该保留平衡(或自动释放池耗尽)。

自动释放永远不能用作跨线程所有权转移原语。

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

【讨论】:

    【解决方案2】:

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

    无论如何,根据文档,保留和释放应该是线程安全的。所以你可能在其他地方有一个错误(可能依赖于也可能不依赖于 iOS 4)。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案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,则需要覆盖两者并使用自己的锁定机制(@synchronize、NSLock 等)。

        @propert(retain) NSObject *atomicObject;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-24
          • 1970-01-01
          • 2011-01-15
          • 1970-01-01
          • 1970-01-01
          • 2011-11-17
          相关资源
          最近更新 更多