在Objective C中全局声明一个函数指针

时间:2015-02-25 19:36:22

标签: objective-c cocoa-touch function-pointers

我想在Objective C中全局声明一个函数指针。我想这样做是因为我正在异步获取通知的更新,并且我希望在收到所有更新后使用完成处理程序。

标题声明如下:

@interface GetStatusUpdate : NSObject 
{
    void (^)(UIBackgroundFetchResult) completionHandler;    
}

-(void)getStatusUpdate:(NSDictionary*)details completionHandler:(void (^)(UIBackgroundFetchResult))completionHandle;

@end

我很高兴(我认为)我正在getStatusUpdate中正确传递完成处理程序,但声明“void(^)(UIBackgroundFetchResult)completionHandler”无法编译。

为了完整起见,我打算:

-(void)getStatusUpdate:(NSDictionary*)journeyDetails
     completionHandler:(void (^)(UIBackgroundFetchResult))completionHandle {

    completionHandler = completionHandle;
}

知道我在这里做错了吗?有关如何在异步提取后使用完成处理程序“更好”的任何建议吗?

2 个答案:

答案 0 :(得分:3)

名称位置错误:

@interface GetStatusUpdate : NSObject 
{ 
    void (^completionHandler)(UIBackgroundFetchResult);    
}

然后,在某些地方,您必须定义块:

completionHandler = ^(UIBackgroundFetchResult result) {
    // do your work
};

或者像你一样分配它。

当我必须处理块时,我觉得这很有用:http://fuckingblocksyntax.com/

另外,您的块被存储为实例变量,不是全局变量。

答案 1 :(得分:2)

Block有时被称为匿名函数。为什么?因为它们没有明确的唯一定义名称(它们是匿名的),并且只能通过它们的签名(输入参数和它们的输出)来区分它们。

所以在你的情况下,没有必要将你的块定义为globaly。 因为什么时候打电话给-(void)getStatusUpdate:completionHandler: 在其他一些类中,您只需构造一个具有相同签名的块,以及块的实现,并将其作为参数传递。

它看起来像这样(注意块实例变量消失了):

@interface GetStatusUpdate : NSObject

-(void)getStatusUpdate:(NSDictionary*)details 
     completionHandler:(void (^)(UIBackgroundFetchResult *result))paramCompletionHandlerBlock;

@end

并在其他类中调用该方法(其中statusUpdateInstance是GetStatusUpdate类的实例),如下所示:

 [statusUpdateInstance getStatusUpdate:detailsDictionaryInstance 
                     completionHandler:^(UIBackgroundFetchResult *result)
                                       {
                                          //code that processes "result"...
                                       }];

顺便说一下。我修复了块签名,输入参数必须命名。


关于块范围的讨论(让你说的更全局化),你需要 typedef 块。它不会是#34;匿名"因为它将被认为是一种独特的类型 在哪里找到块的正确位置?好吧,任何想要调用-(void)getStatusUpdate:completionHandler:方法的类都需要导入GetStatusUpdate类。只有调用该方法的类才真正需要知道该块,而不需要知道其他类。

因此,在GetStatusUpdate类的公共接口中声明和typedef块是唯一有意义的。 我们将为块提供FetchResultsCompletionBlock名称,因为这就是块实际上的作用,它看起来像这样>

typedef void(^FetchResultsCompletionBlock)(UIBackgroundFetchResult *result);

@interface GetStatusUpdate : NSObject

-(void)getStatusUpdate:(NSDictionary*)details completionHandler:(FetchResultsCompletionBlock)completionHandle;

@end

请注意,一旦此块被类型化,即表示不同的已知类型,
-(void)getStatusUpdate:completionHandler:方法的签名被大大简化了。