3

我有一个 NSObject 类别可以在一段时间后执行块。在这种情况下我需要弱化自我吗?

    __weak ViewController *weakSelf = self; 
   [self runBlockAfterDelay:0.6 block:^{

        weakSelf.someview = ...
    }];




 // Category 

- (void)runBlockAfterDelay:(NSTimeInterval)delay block:(void (^)(void))block {

    dispatch_async(dispatch_get_main_queue(), ^{

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

- (void)executeBlockAfterDelay:(void(^)(void))block
{
    if (block)
        block();
}
4

2 回答 2

6

不仅你不需要它(self 对块没有强引用,所以没有循环),如果你包含它,它可能会在你的程序中引入严重的错误。具体来说,在块运行之前没有什么可以阻止“自我”被释放(因为弱引用的全部意义在于它不会阻止事物被释放)。

于 2013-09-26T20:59:31.373 回答
4

只是为@Catfish_Man 的精彩描述添加更多细节:

你可以在块之前弱化自己,在块内你可以再次强化它,以确保它不会在意外的时间被释放。在这种情况下,应确保在释放 self 后不执行该块。这很难,所以只要不创建循环,让它保持强大是一个更安全的选择。(如果 self 持有对块的引用,则将创建循环。)

仅供参考:如果您开始考虑信号而不是程序排序,那么Reactive Cocoa的最终结果会更令人愉悦:

NSTimeInterval delay = 0.3;
// The activator signal that fires after the delay and completes after it.
RACSignal *delayedActivator = [[RACSignal interval:delay] take:1];

@weakify(self)
// The command that we want to execute after the delay.
RACCommand *blockToExecute = [RACCommand command];
[blockToExecute addSignalBlock:^RACSignal *(id value) {
    @strongify(self)
    self.whatever
}];

// Wire up the command on the signal.
[delayedActivator executeCommand:blockToExecute];

乍一看可能有点神秘,但信号可以让你的生活变得更轻松。特别是因为如果信号与self的生命周期相关联,例如它是一个属性,它会在self释放时释放,这样可以确保在不需要时不会执行块。在这种情况下,需要弱化和强化。

于 2013-09-26T21:50:58.753 回答