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

__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(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;
        });
    });

任何信息或解释都将不胜感激!

推荐答案

你不需要做两组弱引用.对于块,您希望避免的是两个对象之间不必要地相互保持活动状态的保留循环.

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

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

我有这个方法:

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

    [self doLongRunningTask];
}

当我把它存放在completionBlock号公寓里时,这座街区将保持活力.但由于它在块内引用self,块将保持self活动,直到它消失,但这不会发生,因为它们都在引用彼此.

在这种方法中:

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

    [self doLongRunningTask];
}

你不需要对self作弱引用.块将保持self的活性,因为它从内部引用self,但由于我们所做的只是将块交给[NSOperationQueue mainQueue],所以self不能保持块的活性.

希望这有帮助.

Objective-c相关问答推荐

Objective-C NSMutableArray 在枚举时发生了变异?

跨平台 iPhone/Android 代码共享

TWTweetComposeViewController 在 IOS6 中已弃用

烦人的[Environment: Sandbox]提示

使用 NSMutableArray 的二维数组

参考代码中的内部版本号或版本号

CF 对象与 NS 对象

如何为图层 shadowOpacity 设置动画?

类在两者中都实现.将使用两者之一

[MFMailComposeViewController canSendMail] 什么时候返回 NO

具有高质量代码的开源 Objective-C 项目?

无法在 Interface Builder (Xcode 5) 中创建与子视图的出口连接

如何使用 iOS 创建一个大的红色 UIButton?

在 UITextField 文本上投影

获取当前调度队列?

UITableView ,重新加载时滚动到底部?

捕捉固定步数的 UISlider(如 iOS 7 设置应用程序中的文本大小)

重复符号问题

Objective C 消息分发机制

UICollectionView:如何检测滚动何时停止