2

例如,调用authenticateHandler

@property(nonatomic, copy) void(^authenticateHandler)(UIViewController *viewController, NSError *error)

小帽子^(UIViewController *viewController, NSError *error)表示调用应该有一个匿名功能块:

[lp setAuthenticateHandler:(^( UIViewController* vc, NSError *nsError )
  {
    if( !nsError )
    {
      puts( "GC auth success" ) ;
    }
  })];

但是假设我希望我在调用中使用的那个函数setAuthenticateHandler是一个命名函数。我见过使用的其他地方@selector(functionName),但这似乎在这里不起作用。

4

2 回答 2

1

块、选择器和函数指针(不确定您将后两者中的哪一个称为命名函数)都是不兼容的类型,因此您不能在需要另一种类型的参数的地方传递一个。幸运的是,如果您确实需要使用基于块的 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

而且,当然,您可以显式调用任何方法或函数,并且接收器和参数都将被块捕获。

于 2013-03-29T06:32:40.470 回答
0

选择器和块是完全不同的概念。

A@selector(functionName)是类型SEL

Ablock是 C 级别的语法运行时特性,在 Objective-C 中,它实际上是一个对象。

有关选择器的更多信息,请查看此处。

有关块的更多信息,请查看此处。

于 2013-03-29T05:31:31.150 回答