全局声明目标C中的函数指针



我想在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;
}

知道我在这里做错了什么吗?有什么建议我可以在异步获取后使用"更好"的完成处理程序吗?

名称在错误的位置:

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

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

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

或者像你一样分配。

当我必须使用块时,我发现这很有帮助:http://fuckingblocksyntax.com/

顺便说一句,您的块存储为实例变量,而不是全局变量。

块有时被称为匿名函数。为什么?因为它们没有唯一定义的独特名称(它们是匿名的),并且实际上仅通过它们的签名(输入参数和输出)来区分自己。

因此,在您的情况下,实际上没有必要全局定义块。因为你什么时候会呼叫-(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"...
                                       }];

Btw。我修复了块签名,输入参数必须命名。


为了使关于块范围的讨论(如您所说,使其更具全局性)有意义,您需要对块进行typedef。它将不再是"匿名",因为它将被视为一种独特的类型
在哪里打字是正确的地方?好吧,任何想要调用-(void)getStatusUpdate:completionHandler:方法的类都需要导入GetStatusUpdate类。只有调用该方法的类才真正需要知道块,而不是其他类。

因此,只有在GetStatusUpdate类的公共接口中声明和typedef该块才有意义。我们将给块起FetchResultsCompletionBlock的名字,因为这是块真正的作用,它看起来像这样>

typedef void(^FetchResultsCompletionBlock)(UIBackgroundFetchResult *result);
@interface GetStatusUpdate : NSObject
-(void)getStatusUpdate:(NSDictionary*)details completionHandler:(FetchResultsCompletionBlock)completionHandle;
@end

注意,一旦这个块被typedefed,即表示一个不同的已知类型,
显著简化了CCD_ 6方法的签名。

最新更新