块、选择器和函数指针(不确定您将后两者中的哪一个称为命名函数)都是不兼容的类型,因此您不能在需要另一种类型的参数的地方传递一个。幸运的是,如果您确实需要使用基于块的 API 的函数指针或选择器,这样做非常容易。块将捕获创建时范围内的函数指针和选择器,您可以在块内使用它们(就像它们对任何其他变量一样)。例如,以下视图控制器为 GCD(基于块的 API)提供了包装器,这些包装器接受选择器或函数指针作为参数:
视图控制器.h:
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
视图控制器.m:
#import "ViewController.h"
void callback() { NSLog(@"call back function"); }
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self doSomethingWithCompletionSelector:@selector(callback)];
// [self doSomethingWithCompletionFunction:callback];
}
- (void)callback
{
NSLog(@"call back selector");
}
- (void)doSomethingWithCompletionSelector:(SEL)selector
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {
NSLog(@"Doing something");
// Causes a warning in ARC
[self performSelector:selector];
});
}
- (void)doSomethingWithCompletionFunction:(void (*)())function
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"Doing something");
function();
});
}
@end
而且,当然,您可以显式调用任何方法或函数,并且接收器和参数都将被块捕获。