为 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。
两个观察:
如果您要定义自己的 setter,它可能看起来像:
- (void)setQueue:(NSOperationQueue *)queue {
_queue = queue;
}
请记住,如果您实现了两种访问器方法(setter 和 getter),则必须手动合成 ivar,例如
@synthesize queue = _queue;
在您的 @implementation
中,因为编译器无法再安全地假设您根本需要特定名称的 ivar。
您应该重新考虑这应该是 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 , 也会消失。
我必须创建一个 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。
两个观察:
如果您要定义自己的 setter,它可能看起来像:
- (void)setQueue:(NSOperationQueue *)queue { _queue = queue; }
请记住,如果您实现了两种访问器方法(setter 和 getter),则必须手动合成 ivar,例如
@synthesize queue = _queue;
在您的
@implementation
中,因为编译器无法再安全地假设您根本需要特定名称的 ivar。您应该重新考虑这应该是
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 , 也会消失。