为 NSOperationQueue 创建一个 Setter

Creating a Setter for NSOperationQueue

我必须创建一个 NSOperationQueue 是原子的。

@property (atomic, strong) NSOperationQueue *queue;

我有这个getter:

- (NSOperationQueue *)queue {
  if (_queue == nil) {
    _queue = [NSOperationQueue mainQueue];
    [_queue setMaxConcurrentOperationCount:1];
  }
  return _queue;
}

但是 Xcode 说我必须创建一个 setter。

我这个案例的 setter 应该如何?我不知道。

首先,您将 属性 "queue" 声明为 read/write 属性。那没有意义。您真的不希望每个人都分配给 "queue"。

其次,您将 属性 声明为 "atomic"。要么你仔细阅读 "atomic" 的作用,要么你只是相信我它很少有用。手写的 getter 或 setter 始终是非原子的。所以你有一个 getter,它是非原子的,因为 属性 本身是一个原子 read/write 属性,你有一个自动生成的 setter是原子的。您不能将非原子 getter 与原子 setter 结合使用,反之亦然。

如何解决:将属性更改为非原子和只读。一个副作用是您丢失了 _queue 支持变量(如果实现了所有必需的访问器,您将不会获得支持变量),因此您必须自己声明 _queue。

两个观察:

  1. 如果您要定义自己的 setter,它可能看起来像:

    - (void)setQueue:(NSOperationQueue *)queue {
        _queue = queue; 
    }
    

    请记住,如果您实现了两种访问器方法(setter 和 getter),则必须手动合成 ivar,例如

    @synthesize queue = _queue;
    

    在您的 @implementation 中,因为编译器无法再安全地假设您根本需要特定名称的 ivar。

  2. 您应该重新考虑这应该是 atomic 还是 nonatomic。您的 getter 不是 atomic(我的示例 setter 也不是),因此您可能只想制作此 nonatomic。正在 atomic "means that the synthesized accessors ensure that a value is always fully retrieved by the getter method or fully set via the setter method, even if the accessors are called simultaneously from different threads"(来自 Programming with Objective-C: Properties are atomic by default)。您通常不需要原子访问器方法,但如果需要,您将更改这些实现以相应地进行同步(例如,使用 NSLock@synchronized 指令、串行队列、reader-作家模式等)。

    请注意,如果您已经做到了 nonatomic,那么您也无需编写自定义 setter 来配合您的自定义 getter。如果您为 atomic 属性 实现了自己的 getter,编译器无法合成相应的 atomic setter,因为它无法知道如何同步它的setter 与您的 getter (因为有许多不同的可能同步机制)。但是如果你让你的 属性 nonatomic 不需要同步,编译器可以为你合成简单的,非同步的 setter,并且警告指示你实现一个 setter , 也会消失。