我正在创建大量的NSOperation
(子类),它们对一堆数据进行排序。当它们完成后,我希望它们“返回”那些数据并将其放入一个可变数组或其他东西中。订单无关紧要。
这样的事情是可能的吗?
答案 0 :(得分:14)
协议委托模式的替代方案是完成块。例如,在一些基于随机NSURLConnection
的操作中,我定义了一个完成块typedef
(以便稍后简化块语法),如果成功则返回NSData
,或者{{1}如果不是:
NSError
然后我可以为我的typedef void(^CustomOperationCompletionBlock)(NSData *data, NSError *error);
子类定义一个块属性,例如:
NSOperation
我经常会对我的@property (nonatomic, copy) CustomOperationCompletionBlock successFailureBlock;
操作方法进行再现,这样我就可以在init
进程中设置完成块(除了我想要初始化的任何其他内容):< / p>
init
我在操作中处理错误和/或成功的各种方法会调用该完成块来传回数据:
- (instancetype)initWithURL:(NSURL *)url successFailureBlock:(CustomOperationCompletionBlock)successFailureBlock;
并且,要将此操作与自定义完成块处理程序一起使用,当我启动操作时,我可以将其传递给自定义完成块。例如,如果成功则保存数据,如果不成功则记录错误:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
if (self.successFailureBlock) {
// whether you call the completion block on the main queue, or use whatever queue the operation is using, is up to you. Here I'll call the completion block on the main queue:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.successFailureBlock(nil, error);
}];
}
[self completeOperation];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
if (self.successFailureBlock) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.successFailureBlock(self.data, nil);
}];
}
[self completeOperation];
}
显然,您可以更改块CustomOperation *operation = [[CustomOperation alloc] initWithURL:url successFailureBlock:^(NSData *data, NSError *error) {
if (error)
NSLog(@"CustomOperation error: %@", error);
else
[data writeToFile:path atomically:YES];
}];
[queue addOperation:operation];
以传回对您的操作有意义的任何对象。但这说明了typedef
子类返回数据的基于块的机制的基本模式。
答案 1 :(得分:4)
不确定。在NSOperation子类中声明委托。然后在完成操作后
if([self.delegate respondsToSelector:@selector(YourDelegate:)]) {
[(NSObject *)self.delegate performSelectorOnMainThread:@selector(YourDelegate:) withObject:self waitUntilDone:NO];
}
在UI中
-(void)YourOperationDidFinish:(YourOperation *)downloader {
if(downloader.downloadItem) {
// processing with your object
}
}