将Objective-C块传递给performSelector是否安全:withObject:afterDelay:?

时间:2014-02-20 21:59:42

标签: ios objective-c memory-management automatic-ref-counting nsobject

我想将一个块参数传递给-performSelector:withObject:afterDelay:。 例如,考虑一下:

[self performSelector:@selector(delayedBlock:) withObject:^{
    // some code in block
} afterDelay:2];

- (void)delayedBlock:(void (^)(void))code {
    code();
}

它有效但我不确定是否因为ARC而需要做一些特别的事情。

2 个答案:

答案 0 :(得分:0)

正如rmaddy在评论中写道,有更好的方法可以延迟执行一个块,但如果你想使用performSelector:withObject:afterDelay:,你应该复制该块。

[self performSelector:@selector(delayedBlock:) withObject:[^{
    // some code in block
} copy] afterDelay:2];

来自Blocks Programming Topics

  

通常,您不需要复制(或保留)块。当您希望在销毁声明范围之后使用该块时,您只需要制作一个副本。复制将块移动到堆中。

答案 1 :(得分:0)

您可以直接使用 GCD

这是一个基于GCD的简单技术,我正在使用:

void RunBlockAfterDelay(NSTimeInterval delay, void (^block)(void))
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*delay),
      dispatch_get_current_queue(), block);
}

或使用此有用的类别

@implementation NSObject (PerformBlockAfterDelay)


- (void)performBlock:(void (^)(void))block 
          afterDelay:(NSTimeInterval)delay 
{
    block = [block copy];

    [self performSelector:@selector(fireBlockAfterDelay:) 
               withObject:block 
               afterDelay:delay];
}

- (void)fireBlockAfterDelay:(void (^)(void))block
{
    block();
}

@end

查看此主题中的讨论: Blocks instead of performSelector:withObject:afterDelay: