Iphone 目标-C将块传递到块中
这是一个有点棘手的场景。我一直在研究块并第一次开始实现它们,我发现自己想要创建一个“复合块”。这是我的代码,大致如下:Iphone 目标-C将块传递到块中,iphone,retain,block,Iphone,Retain,Block,这是一个有点棘手的场景。我一直在研究块并第一次开始实现它们,我发现自己想要创建一个“复合块”。这是我的代码,大致如下: - (void)moveToPosition:(NSInteger)pos withVelocity:(CGFloat)vel onCompletion:(void(^)(BOOL completed))completionBlock { void (^compoundBlock) (BOOL completed) = ^(BOOL completed) {
- (void)moveToPosition:(NSInteger)pos withVelocity:(CGFloat)vel onCompletion:(void(^)(BOOL completed))completionBlock
{
void (^compoundBlock) (BOOL completed) = ^(BOOL completed) {
[self unlockInteractionFromPullDownMenuTab];
void(^innerCompletionBlock)(BOOL completed) = completionBlock;
innerCompletionBlock(completed);
};
// Animate
[UIView animateWithDuration: duration
animations: ^void{ [self.pullDownMenu setFrame:newFrame]; }
completion: compoundBlock
];
}
目标是获取传递到此方法中的代码块,向其添加一些内容,然后将其传递到动画方法调用中。但是,我在线路上的访问权限不好:
innerCompletionBlock(completed);
我认为我的innerCompletionBlock正在被释放,但我不完全确定原因。据我所知,块复制了你扔给它们的所有东西,包括对self的引用——它可以创建保留循环,而我最近学会了避免这种循环
实际上,我最初试过这个:
void (^compoundBlock) (BOOL completed) = ^(BOOL completed) {
[self unlockInteractionFromPullDownMenuTab];
completionBlock(completed);
};
但是我得到的是错误的访问,我认为可能compoundBlock没有复制completionBlock,所以我在块内显式声明了一个(block)变量,并分配给它,试图让它保留(可能有点傻,但我在ARC下运行,所以我无法进行手动保留调用)
无论如何,很明显,当compoundBlock传递到UIView时,它会被保留,但我不确定如何在compoundBlock中保留onCompletion/innerCompletionBlock,因为我在ARC下运行
提前感谢:)在堆栈上创建块。您需要将
completionBlock
复制到堆中,以便在尝试运行它时确保它仍然有效。只需将此放在方法的顶部:
completionBlock = [completionBlock copy];
请注意,如果堆上已经存在
completionBlock
,则只返回相同的堆副本。Aha,解决它。真的有点愚蠢
我多次调用方法-(void)moveToPosition:…
并将nil
传递给completionBlock
参数…因为我在动画结束时不需要做任何额外的事情,只需要[self-unlockInteractionFromPullDownMenuTab]代码>是在复合块中附加的
有道理,对吧
…只有在调用块之前检查是否为零。如前所述,“当您执行一个块时,首先测试该块是否为nil很重要”。嗯,我在那里学到了教训
此代码适用于:
// Compound completion block
void (^compoundBlock) (BOOL completed) = ^(BOOL completed) {
[self unlockInteractionFromPullDownMenuTab];
if (completionBlock != nil) {
completionBlock(completed);
}
};
嗯…谢谢你的快速回答。我有一个问题:在ARC下是否仍然需要复制块?(似乎不是。)为了论证,如果我上面的示例中的两个块没有在ARC下运行,我将如何准确地调用copy?只需在方法顶部的completionBlock
上复制一次,但不要复制到compoundBlock
,因为UIView动画调用会在内部复制它本身?谢谢。如果不在ARC下,则每个副本
必须通过释放
或自动释放
进行平衡。在许多情况下,没有必要在ARC下复制一个块,但仍有一些情况是必要的,所以我倾向于预防性地复制。这是不正确的。他不需要在MRC或ARC中显式复制示例中的块completionBlock
。该方法不存储completionBlock
,以供以后在任何地方使用,除非被另一个块compoundBlock
捕获。当(如果)compoundBlock
被复制时,它将自动复制completionBlock
。