我想为某个类创建一个完成处理程序,而不是触发类的主代码并等待委托回调。我已经阅读了 Apple 文档,他们似乎没有给出一个很好的例子来说明如何直接实现这样的东西。
4 回答
您需要将完成块视为变量。该方法将接受一个块作为其参数的一部分,然后将其存储以备后用。
- (void)myMethodWithCompletionHandler:(void (^)(id, NSError*))handler;
您可以 typedef 该块类型以便于阅读:
typedef void (^CompletionBlock)(id, NSError*);
然后将您的块存储为实例变量:
在您的@interface 中:CompletionBlock _block;
在 myMethod.._block = [handler copy]
然后,当您希望完成块执行时,您只需像常规块一样调用它:
_block(myData, error);
如果是异步方法,你可以这样做
- (void)asynchronousTaskWithCompletion:(void (^)(void))completion;
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Some long running task you want on another thread
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) {
completion();
}
});
});
}
这将被调用
[self asynchronousTaskWithCompletion:^{
NSLog(@"It finished");
}];
需要注意的是守卫确保它completion
指向某个东西,否则如果我们尝试执行它会崩溃。
我经常将块用于完成处理程序的另一种方式是当 viewController 完成并希望从导航堆栈中弹出时。
@interface MyViewController : UIViewController
@property (nonatomic, copy) void (^onCompletion)(void);
@end
@implementation MyViewController
- (IBAction)doneTapped;
{
if (self.onCompletion) {
self.onCompletion();
}
}
@end
将此视图推送到堆栈时,您将设置完成块
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;
{
MyViewController *myViewController = segue.destinationViewController;
myViewController.onCompletion = ^{
[self.navigationController popViewControllerAnimated:YES];
};
}
Heres an example for a method that takes a String and a completion handler as variables. The completion handler can also receive a String.
Swift 2.2 Syntax
Defintion:
func doSomething(input: String, completion: (result: String) -> Void {
print(input)
completion(result: "we are done!")
}
Calling the function:
doSomething("cool put string!") { (result) in
print(result)
}