过去,一般建议直接访问和设置支持setter属性的变量,而不是属性本身。
例如:
- (void)setSomething:(id)thing {
_something = thing;
[_collectionView reloadData];
}
而不是:
- (void)setSomething:(id)thing {
_something = thing;
[self.collectionView reloadData];
}
这种方法效果很好,但是块存在一些模糊性,特别是对于内存管理。举个例子:
- (void)setSomething:(id)thing {
_something = thing;
[_collectionView performBatchUpdates:^{...} completion:^(BOOL finished) {
[_something doTheThing];
}];
}
这现在在Xcode中生成警告,说" Block隐含地保留' self&#39 ;;明确提及' self'表明这是预期的行为"
这里有什么建议,我应该使用self.collectionView
还是self->_collectionView
?
答案 0 :(得分:3)
您的警告只是说应该避免使用ivar对self
的隐含引用。这并不意味着您需要跳转到使用访问器方法。例如,您可以只显式引用self
,并且应该删除错误消息:
- (void)setSomething:(id)thing {
_something = thing;
[_collectionView performBatchUpdates:^{...} completion:^(BOOL finished) {
[self->_something doTheThing];
}];
}
或者更好的是,在完成版块模式中,如果您想在完成块完成之前避免保留self
,则可以进行weakSelf
/ strongSelf
舞蹈,完全避免任何强引用周期的风险,并且如果视图控制器在self
之前调用其完成处理程序,则允许performBatchUpdates
取消分配:
- (void)setSomething:(id)thing {
_something = thing;
__weak typeof(self) weakSelf = self;
[_collectionView performBatchUpdates:^{...} completion:^(BOOL finished) {
typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf->_something doTheThing];
}
}];
}