将完成处理程序保存为对象

时间:2013-10-04 00:19:40

标签: ios objective-c

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

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

}

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

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

3 个答案:

答案 0 :(得分:30)

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中的成熟对象, BUT 它们有很大的不同:默认情况下它们是在堆栈上分配的。

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

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

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

答案 1 :(得分:2)

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

所以你需要做任何一件事:

_myCompletionHandler = [completionHandler copy];

或:

_myCompletionHandler = Block_copy(completionHandler);

答案 2 :(得分:2)

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

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

然后你可以说self.blockName = completionHandler

actionHere中,只需将其称为:

self.blockName();