iOS最强大的定位内存泄露工具
2016-06-06 本文已影响596人
小如99
以下原代码是使用MLeaksFinder定位到报错的代码,纠正后为不存在泄露的代码
-
原代码一:
UIButton *btn = [self createBtnWithTitle:title]; /*! 监听点击事件 */ [btn bk_whenTapped:^{ int tag = (int)btn.tag; self.selectedBtnType = tag; self.clicked(tag); }];
纠正后:
int tag = (int)btn.tag;
/*! 监听点击事件 */
__weak typeof(self) weakSelf = self;
[btn bk_whenTapped:^{
weakSelf.selectedBtnType = tag;
weakSelf.clicked(tag);
}];
-
原代码二:
[_shareBtn bk_whenTapped:^{ _shareClicked(); }];
纠正后:
__weak typeof(self) weakSelf = self;
[_shareBtn bk_whenTapped:^{
weakSelf.shareClicked();
}];
- 原代码三:
[_rightBackBtn bk_whenTapped:^{
[self.viewController.navigationController popViewControllerAnimated:YES];
}];
纠正后:
[_rightBackBtn bk_whenTapped:^{
[weakSelf.viewController.navigationController popViewControllerAnimated:YES];
}];
- 原代码四:
__weak typeof(self) weakSelf = self;
[propertyView addObserverBlockForKeyPath:@"selectedSku" block:^(__weak id obj, ALGoodsSKUItem *oldItem, ALGoodsSKUItem *newItem) {
if (![newItem.SKUID isEqualToString:oldItem.SKUID]) {
_currShowSkuItem = newItem;
weakSelf.requestActivityData();
}
}];
纠正后:
__weak typeof(self) weakSelf = self;
[propertyView addObserverBlockForKeyPath:@"selectedSku" block:^(__weak id obj, ALGoodsSKUItem *oldItem, ALGoodsSKUItem *newItem) {
if (![newItem.SKUID isEqualToString:oldItem.SKUID]) {
weakSelf.currShowSkuItem = newItem;
weakSelf.requestActivityData();
}
}];
- 原代码五:
/*! 监听address的frame,当需要显示身份视图的时候修改其他视图的位置 */
/*! headerTitleView/headerView/headerTitleView/addressView 都是局部对象变量 */
__weak typeof(self) weakSelf = self;
[self.addressView addObserverBlockForKeyPath:@"frame" block:^(__weak id obj, id oldVal, id newVal) {
headerTitleView.top = addressView.bottom;
headerView.height = headerTitleView.bottom;
weakSelf.tableView.tableHeaderView = headerView;
}];
纠正后:
/*! 监听address的frame,当需要显示身份视图的时候修改其他视图的位置 */
/*! headerTitleView/headerView/headerTitleView/addressView 都是局部对象变量 */
__weak typeof(self) weakSelf = self;
__weak typeof(headerTitleView) weakHeaderTitleView = headerTitleView;
__weak typeof(addressView) weakAddressView = addressView;
__weak typeof(headerView) weakHeaderView = headerView;
[self.addressView addObserverBlockForKeyPath:@"frame" block:^(__weak id obj, id oldVal, id newVal) {
weakHeaderTitleView.top = weakAddressView.bottom;
weakHeaderView.height = weakHeaderTitleView.bottom;
weakSelf.tableView.tableHeaderView = weakHeaderView;
}];
总结:这个地方我调试了很久,有用过__block来修饰局部对象,不起作用,这里贴上__block和__weak的区别
*__block和__weak的区别:
1.在MRC环境下,__block是弱引用,在ARC环境下是强引用
2.__block本身无法避免循环引用的问题,但是我们可以通过在 block 内部手动把 blockObj 赋值为 nil 的方式来避免循环引用的问题。另外一点就是 __block修饰的变量在 block 内外都是唯一的,要注意这个特性可能带来的隐患。
3.__weak本身是可以避免循环引用的问题的,但是其会导致外部对象释放了之后,block 内部也访问不到这个对象的问题,我们可以通过在 block 内部声明一个strong的变量来指向 weakObj,使外部对象既能在 block 内部保持住,又能避免循环引用的问题。
- 原代码五:
_mainView = self.superview; /*! _mainView为成员变量 */
纠正后:
去掉_mainView的变量,用到_mainView的用self.superview代替就解决了