2015-03-13 36 views
1

Marcus Zarra's "Core Data" (2nd edition)书中列举其中的NSOperation子,他重写了completionBlock属性的示例:重写具有不同参数类型的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下10.10导致以下警告:

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

and

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

现在我想知道我应该怎么做这些警告。
原子性属性如何?
尽管出现警告,可以更改参数吗?
是否有另一个更好的解决方案,不涉及更改块参数?

回答

2

那么原子性属性呢?

atomicnonatomic真的很让人困惑。 NSOperation是一个需要原子属性的地方。除非你有很好的理由,否则我会坚持使用atomic

尽管出现警告,可以更改参数吗?

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

是否有另一个更好的解决方案,不涉及更改块参数?

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

@property (atomic, copy) ExportCompletionBlock exportCompletionBlock; 

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

+0

“您不必强制使用completionBlock,使用不同的名称创建一个新的属性。”这似乎工作。但是,我将如何了解它呢?另外'completionBlock'上的文档说:“在iOS 8及更高版本和OS X v10.10及更高版本中,在完成块开始执行后,此属性设置为零。”这也会发生在我自己的名称不同的块属性中吗? – MartinW 2015-03-16 13:45:52

+0

@MartinW我不知道如何回答你的第一个问题。你可以在你的子类中控制'-main'中的所有内容,这样你就可以做任何你想做的事情。如果你不调用'-completionBlock',那么它是一个未使用的属性。 – 2015-03-16 13:53:55

+0

@MartinW至于你的第二个问题,'NSO​​peration'不知道你的子类的属性。如果价值发生了变化,我会感到非常惊讶。 – 2015-03-16 13:58:19

相关问题