为什么不总是在块中使用weakSelf?

时间:2013-01-29 16:46:47

标签: objective-c objective-c-blocks

我明白为什么我们会在一个区块中使用weakSelf,而不是在什么时候。

我正在将一个代码库转换为ARC,它给出了很多带块的保留周期警告。从我收集的文档中我需要改变它:

[self.selectedAsset addToFavoritesWithCompletion:^(NSError *error) {
    self.selectedAsset.isFavorite = YES;
    [self updateIsFavoriteButton];
}];

到此:

__weak MyViewController* weakSelf = self;
[self.selectedAsset addToFavoritesWithCompletion:^(NSError *error) {
    self.selectedAsset.isFavorite = YES;
    [weakSelf updateIsFavoriteButton];
}];

使编译器满意并避免保留循环。我的问题是为什么没有必要改变这条线:

self.selectedAsset.isFavorite = YES;

使用weakSelf?它也不评估方法调用吗?为什么编译器不警告这种格式的行?

[[self selectedAsset]setIsFavorite:YES];
编辑:我刚刚更新到XCode 4.6,它现在为这种情况生成编译器警告。有趣的时机:))

2 个答案:

答案 0 :(得分:8)

  

我的问题是为什么没有必要更改这一行:

     

self.selectedAsset.isFavorite = YES;使用weakSelf?不是吗   评估一个方法调用?编译器为什么不警告   这种格式的行?

     

[[self selectedAsset]setIsFavorite:YES];

是的,这正是一个方法调用。它确实引用了self的强引用。如果您希望不保留weakSelf,则必须将其更改为self

编译器警告不会捕获所有内容。

答案 1 :(得分:1)

__weak MyViewController* weakSelf = self;
[self.selectedAsset addToFavoritesWithCompletion:^(NSError *error) {
    self.selectedAsset.isFavorite = YES;
    [weakSelf updateIsFavoriteButton];
}];

确实是愚蠢的。完成块引用self两次,这将创建一个强引用。它仍然引用自我一次,仍然创造了一个强大的参考。如果您使用强引用,那么弱引用也毫无意义。这应该是

__weak MyViewController* weakSelf = self;
[self.selectedAsset addToFavoritesWithCompletion:^(NSError *error) {
    weakSelf.selectedAsset.isFavorite = YES;
    [weakSelf updateIsFavoriteButton];
}];

或更好(因为更安全)

__weak typeof (self) weakSelf = self;
[self.selectedAsset addToFavoritesWithCompletion:^(NSError *error) {
    typeof (self) strongSelf = weakSelf;
    strongSelf.selectedAsset.isFavorite = YES;
    [strongSelf updateIsFavoriteButton];
}];