我明白为什么我们会在一个区块中使用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,它现在为这种情况生成编译器警告。有趣的时机:))
答案 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];
}];