在 Objective C 中全局声明一个函数指针
Globally declaring a function pointer in Objective C
我想在 Objective C 中全局声明一个函数指针。我想这样做是因为我正在异步获取通知的更新,并且我希望在收到所有更新后使用完成处理程序。
header声明如下:
@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;
}
知道我做错了什么吗?对我如何在异步获取后使用完成处理程序 'better' 有什么建议吗?
名字放错地方了:
@interface GetStatusUpdate : NSObject
{
void (^completionHandler)(UIBackgroundFetchResult);
}
然后,在某些地方,您必须定义块:
completionHandler = ^(UIBackgroundFetchResult result) {
// do your work
};
或像您一样分配它。
当我必须使用块时,我发现这很有用:http://fuckingblocksyntax.com/
顺便说一句,您的块被存储为实例变量,不是全局变量。
块有时被称为匿名函数。为什么?因为它们没有明确的唯一定义名称(它们是匿名的)并且仅通过它们的签名(输入参数和它们的输出)真正区分它们自己。
所以在你的情况下,没有必要全局定义你的块。
因为当你调用 -(void)getStatusUpdate:completionHandler:
在其他一些 class 中,您将简单地构建一个具有相同签名的块,连同块的实现并将其作为参数传递。
它看起来像这样(注意块实例变量消失了):
@interface GetStatusUpdate : NSObject
-(void)getStatusUpdate:(NSDictionary*)details
completionHandler:(void (^)(UIBackgroundFetchResult *result))paramCompletionHandlerBlock;
@end
并在其他 class 中调用该方法(其中 statusUpdateInstance 是 GetStatusUpdate class 的实例),如下所示:
[statusUpdateInstance getStatusUpdate:detailsDictionaryInstance
completionHandler:^(UIBackgroundFetchResult *result)
{
//code that processes "result"...
}];
顺便说一句。我修复了块签名,输入参数必须命名。
为了使有关块范围的讨论(如您所说的更全局化)变得有意义,您需要 typedef块。它将不再是 "anonymous",因为它将被视为一种独特的类型。
typedef 块的正确位置在哪里?那么,任何想要调用 -(void)getStatusUpdate:completionHandler:
方法的 class 都需要导入 GetStatusUpdate
class。只有调用该方法的 classes 才真正需要知道该块,没有其他人。
因此只有在 GetStatusUpdate
class 的 public 接口中声明和定义该块才有意义。
我们将给块起 FetchResultsCompletionBlock
名称,因为这是块真正做的事情,它看起来像这样>
typedef void(^FetchResultsCompletionBlock)(UIBackgroundFetchResult *result);
@interface GetStatusUpdate : NSObject
-(void)getStatusUpdate:(NSDictionary*)details completionHandler:(FetchResultsCompletionBlock)completionHandle;
@end
请注意,一旦这个块被类型定义,即代表一个不同的已知类型,
-(void)getStatusUpdate:completionHandler:
方法的签名大大简化。
我想在 Objective C 中全局声明一个函数指针。我想这样做是因为我正在异步获取通知的更新,并且我希望在收到所有更新后使用完成处理程序。
header声明如下:
@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;
}
知道我做错了什么吗?对我如何在异步获取后使用完成处理程序 'better' 有什么建议吗?
名字放错地方了:
@interface GetStatusUpdate : NSObject
{
void (^completionHandler)(UIBackgroundFetchResult);
}
然后,在某些地方,您必须定义块:
completionHandler = ^(UIBackgroundFetchResult result) {
// do your work
};
或像您一样分配它。
当我必须使用块时,我发现这很有用:http://fuckingblocksyntax.com/
顺便说一句,您的块被存储为实例变量,不是全局变量。
块有时被称为匿名函数。为什么?因为它们没有明确的唯一定义名称(它们是匿名的)并且仅通过它们的签名(输入参数和它们的输出)真正区分它们自己。
所以在你的情况下,没有必要全局定义你的块。
因为当你调用 -(void)getStatusUpdate:completionHandler:
在其他一些 class 中,您将简单地构建一个具有相同签名的块,连同块的实现并将其作为参数传递。
它看起来像这样(注意块实例变量消失了):
@interface GetStatusUpdate : NSObject
-(void)getStatusUpdate:(NSDictionary*)details
completionHandler:(void (^)(UIBackgroundFetchResult *result))paramCompletionHandlerBlock;
@end
并在其他 class 中调用该方法(其中 statusUpdateInstance 是 GetStatusUpdate class 的实例),如下所示:
[statusUpdateInstance getStatusUpdate:detailsDictionaryInstance
completionHandler:^(UIBackgroundFetchResult *result)
{
//code that processes "result"...
}];
顺便说一句。我修复了块签名,输入参数必须命名。
为了使有关块范围的讨论(如您所说的更全局化)变得有意义,您需要 typedef块。它将不再是 "anonymous",因为它将被视为一种独特的类型。
typedef 块的正确位置在哪里?那么,任何想要调用 -(void)getStatusUpdate:completionHandler:
方法的 class 都需要导入 GetStatusUpdate
class。只有调用该方法的 classes 才真正需要知道该块,没有其他人。
因此只有在 GetStatusUpdate
class 的 public 接口中声明和定义该块才有意义。
我们将给块起 FetchResultsCompletionBlock
名称,因为这是块真正做的事情,它看起来像这样>
typedef void(^FetchResultsCompletionBlock)(UIBackgroundFetchResult *result);
@interface GetStatusUpdate : NSObject
-(void)getStatusUpdate:(NSDictionary*)details completionHandler:(FetchResultsCompletionBlock)completionHandle;
@end
请注意,一旦这个块被类型定义,即代表一个不同的已知类型,
-(void)getStatusUpdate:completionHandler:
方法的签名大大简化。