深刻理解iosBlock
///一個控制器裡的方法
- (void)setRefreshHeader {
ACWeakSelf(self);
self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
if (weakSelf.dataSource.count) {
_messageTime = [weakSelf.dataSource[0] date_created];
// weakSelf.messageTime = [weakSelf.dataSource[0] date_created];修改之後的程式碼
}
[[ACChatManager sharedInstance]loadMessagesWithMessageTime:_messageTime /* weakSelf.messageTime修改之後的程式碼*/direction:ACLoadMessageDirectionUp completion:^(NSArray *messages, NSError *error) {
[weakSelf.tableView.mj_header endRefreshing];
if (!error) {
if (messages.count) {
NSInteger scrollIndex = weakSelf.dataSource.count;
[weakSelf.dataSource insertObjects:messages atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, messages.count)]];
[weakSelf.tableView reloadData];
[weakSelf.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:weakSelf.dataSource.count - scrollIndex inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:false];
}else {
weakSelf.tableView.mj_header.hidden = true;
}
}
}];
}];
}
先不需要看註釋的部分,整體看一遍這個程式碼你有沒有發現有什麼問題這個程式碼?
這個修改一個同事的程式碼發現的問題,特此做一個筆記。注意到註釋的兩個地方,都是用的直接取屬性而沒有用到getter方法,也就是這裡會引發一個巨大的問題,那就是記憶體洩漏,這個控制器不會釋放,引起他的原因就是造成了block迴圈引用。那麼挖掘根本是什麼造成了迴圈引用,通過getter方法獲取屬性和setter方法去設定屬性有什麼區別?
區別就是通過”_”是直接訪問屬性(或者叫做直接訪問成員變數)而通過”self.”是通過這個物件去檢視屬性。所以建議在block裡儘量都是用self來訪問。而且block裡儘量不要套太多的block!