可以用不同的参数类型覆盖 NSOperation 的 completionBlock 属性 吗?

Is it ok to override completionBlock property of NSOperation with different parameter types?

Marcus Zarra's "Core Data" (2nd edition) 书中列出了一个示例,其中在 NSOperation 子类中他覆盖了 completionBlock 属性:

@property (copy) void (^completionBlock)(void) NS_AVAILABLE(10_6, 4_0);

typedef void (^ExportCompletionBlock)(NSData *jsonData, NSError *error);
@property (nonatomic, copy) ExportCompletionBlock completionBlock;

在 Xcode 6 under 10.10 中导致以下警告:

‘atomic’ attribute on property ‘completionBlock’ does not match the property inherited from ‘NSOperation’

Property type ‘ExportCompletionBlock’ (aka ‘void(^)(NSData *_strong, NSError *_strong)’) is incompatible with type ‘void(^)(void)’ inherited from ‘NSOperation’

现在我想知道我应该如何看待这些警告。
原子性属性呢?
是否可以不顾警告更改参数?
有没有其他更好的解决方案,不涉及更改块参数?

What about the atomicity attribute?

atomicnonatomic 真的很混乱。 NSOperation 是需要原子属性的地方。除非你有充分的理由,否则我会坚持 atomic

Is it ok to change the parameters despite the warning?

警告是有原因的。 completionBlock 属性 预计会以某种方式工作,如果它以某种方式被调用时使用其原始签名 (self.completionBlock()) 而不是重新定义的签名 (self.completionBlock(jsonData, error)),那么您的应用程序会崩溃。

Is there another, better solution that does not involve changing the block parameters?

不要重新定义 completionBlock。您不是被迫使用 completionBlock,而是用不同的名称创建一个新的 属性。例如,在您的子类中,您可以使用 exportCompletionBlock:

@property (atomic, copy) ExportCompletionBlock exportCompletionBlock;

然后,在 -main 中,当操作完成时调用 self.exportCompletionBlock(jsonData, error) 而不是 self.completionBlock(jsonData, error)