我正在创建许多NSOperations(子类),它们通过一堆数据进行排序.当它们完成后,我希望它们"返回"那些数据并将其放入一个可变数组或其他东西.订单无关紧要.
这样的事情有可能吗?
Rob*_*Rob 14
协议委托模式的替代方案是完成块.例如,在一些NSURLConnection基于随机的操作中,我定义了一个完成块typedef(以便稍后简化块语法),它返回NSDataif成功,或者NSError如果不是:
typedef void(^CustomOperationCompletionBlock)(NSData *data, NSError *error);
Run Code Online (Sandbox Code Playgroud)
然后我可以为我的NSOperation子类定义一个块属性,例如:
@property (nonatomic, copy) CustomOperationCompletionBlock successFailureBlock;
Run Code Online (Sandbox Code Playgroud)
我经常会对init我的操作方法进行再现,这将让我在此init过程中设置完成块(除了我想要初始化的任何其他内容):
- (instancetype)initWithURL:(NSURL *)url successFailureBlock:(CustomOperationCompletionBlock)successFailureBlock;
Run Code Online (Sandbox Code Playgroud)
我在操作中处理错误和/或成功的各种方法然后会调用该完成块来传回数据:
- (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];
}
Run Code Online (Sandbox Code Playgroud)
并且,要将此操作与自定义完成块处理程序一起使用,当我启动操作时,我可以将其传递给自定义完成块.例如,如果成功则保存数据,如果不成功则记录错误:
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];
Run Code Online (Sandbox Code Playgroud)
显然,您可以更改块typedef以传回对您的操作有意义的任何对象.但这说明了NSOperation子类返回数据的基于块的机制的基本模式.
当然。在 NSOperation 子类中声明一个委托。然后运行完成后
if([self.delegate respondsToSelector:@selector(YourDelegate:)]) {
[(NSObject *)self.delegate performSelectorOnMainThread:@selector(YourDelegate:) withObject:self waitUntilDone:NO];
}
Run Code Online (Sandbox Code Playgroud)
在用户界面中
-(void)YourOperationDidFinish:(YourOperation *)downloader {
if(downloader.downloadItem) {
// processing with your object
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3485 次 |
| 最近记录: |