iOS block 和对自身的强/弱引用

标签 ios objective-c objective-c-blocks

我有一个关于 iOS block 中对 self 的强引用和弱引用的问题。我知道在 block 内引用 self 的正确方法是在 block 外创建一个弱引用,然后在 block 内创建一个对该弱引用的强引用,如下所示:

__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^ {
    typeof(self) strongSelf = weakSelf;
    NSLog(@"%@", strongSelf.someProperty);
});

但是,如果您有嵌套 block 会发生什么?一套引用文献就够了吗?或者您是否需要为每个 block 设置一个新集?例如,下列哪项是正确的?

这个:

__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^ {
    typeof(self) strongSelf = weakSelf;
    NSLog(@"%@", strongSelf.someProperty);
    dispatch_async(dispatch_get_main_queue(), ^ {
        strongSelf.view.frame = CGRectZero;
    });
});

或者这个:

__weak typeof(self) weakSelf = self;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^ {
        typeof(self) strongSelf = weakSelf;
        NSLog(@"%@", strongSelf.someProperty);
        __weak typeof(strongSelf) weakSelf1 = strongSelf;
        dispatch_async(dispatch_get_main_queue(), ^ {
            typeof(strongSelf) strongSelf1 = weakSelf1;
            strongSelf1.view.frame = CGRectZero;
        });
    });

非常感谢任何信息或解释!

最佳答案

你不需要做两组弱引用。使用 block 要避免的是保留循环——两个对象在不必要的情况下使彼此保持事件状态。

如果我有一个具有此属性的对象:

@property (strong) void(^completionBlock)(void);

我有这个方法:

- (void)doSomething
{
    self.completionBlock = ^{
        [self cleanUp];
    };

    [self doLongRunningTask];
}

当我将它存储在 completionBlock 属性中时,该 block 将保持事件状态。但由于它在 block 内引用 self,因此该 block 将保持 self 事件直到它消失——但这不会发生,因为它们都在相互引用。

在这个方法中:

- (void)doSomething
{
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        [self cleanUp];
    }];

    [self doLongRunningTask];
}

您不需要对 self 进行弱引用。该 block 将保持 self 事件,因为它从内部引用 self,但由于我们所做的只是将 block 交给 [NSOperationQueue mainQueue]self 并没有使 block 保持事件状态。

希望这会有所帮助。

关于iOS block 和对自身的强/弱引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19018456/

相关文章:

ios - 对旧版本的iPhone禁用iPhone应用程序

ios - 从 map 注释标注的过渡

objective-c - 在Cocoa/Obj-C中,如何捕获cmd-c事件?

ios - 从类方法中的 block 返回值

objective-c - 在 OCMock 中使用 block 期望

ios - [UIViewAnimationStateanimationDidStop :finished:]: message sent to deallocated instance

ios - 为什么 .crash 日志在 UIPresentationController 中显示崩溃,但我的应用程序不使用 UIPresentationController?

ios - 如何在应用程序运行时更改 NavigationBarColor

ios - UITableviewCell textLabel在iOS7中不可见

objective-c - Objective-c 中的 Smalltalk block ?