美文网首页
iOS最强大的定位内存泄露工具

iOS最强大的定位内存泄露工具

作者: 小如99 | 来源:发表于2016-06-06 17:41 被阅读596次

    MLeaksFinder

    以下原代码是使用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代替就解决了

    相关文章

      网友评论

          本文标题:iOS最强大的定位内存泄露工具

          本文链接:https://www.haomeiwen.com/subject/iefldttx.html