13

我想知道是否有办法“保存”完成处理程序。

-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{

}

- (void)actionHere {
    completionHandler(UIBackgroundFetchResultNewData);
}

我想用不同的函数发送结果,如上所示。

4

3 回答 3

33

tl;博士

声明一个复制属性(奇怪的语法,我知道... http://fuckingblocksyntax.com/

@property (nonatomic, copy) void (^completionHandler)(UIBackgroundFetchResult fetchResult);

并像下面这样使用它

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    self.completionHandler = completionHandler;
}

- (void)actionHere {
    if (self.completionHandler)
        self.completionHandler(UIBackgroundFetchResultNewData);
}

讨论

在 Objective-C 中,块是成熟的对象,它们有一个很大的不同:默认情况下它们是在堆栈上分配的。

如果要保存对块的引用,则必须将其复制到堆上,因为在堆栈上保留一个块不会阻止它在堆栈帧被拆除时丢失。

为了复制堆上的块,您必须调用该Block_Copy()函数。您可以选择调用该copy方法(它将为您调用上一个函数)。

使用属性声明copy属性将使编译器copy在您通过属性设置器分配对象时自动插入调用。

于 2013-10-04T01:00:38.730 回答
2

块是对象(是的,真正的 ObjC 对象!),唯一重要的是您必须在想要存储它们以供以后使用时复制它们(而不是保留)。

因此,您需要执行以下任一操作:

_myCompletionHandler = [completionHandler copy];

或者:

_myCompletionHandler = Block_copy(completionHandler);
于 2013-10-04T00:23:59.867 回答
2

您需要为您的块声明一个属性。这是语法:

@property (nonatomic, copy) returnType (^blockName)(parameterTypes);

然后你可以说self.blockName = completionHandler

actionHere就像这样称呼它:

self.blockName();
于 2013-10-04T00:49:45.187 回答