removeFromSuperView后内存未释放

无敌鲨鱼炮
  • 448

我封装了一个UIScrollView的占位图,用于当UIScrollView及其子类的数据源为空时展示,效果如下:
图片描述

点击重新加载按钮后这个占位图从UIScrollView上移除,但是,内存并没有降低,我点击返回按钮pop到上一页,视图控制器的dealloc方法执行了,但是内存并未下降。

然后我用instrument检查内存泄漏情况,并未检测出内存泄漏,但是每次展示占位图内存都会增加,移除后却不降低,就这样内存越来越大,我觉得肯定是我写的这个方法里有问题:

/**
 展示UIScrollView及其子类的占位图
 
 @param type 占位图类型
 @param reloadBlock 重新加载回调的block
 */
- (void)showPlaceholderViewWithType:(CQPlaceholderViewType)type reloadBlock:(void (^)())reloadBlock {
    //------- 背景view -------//
    UIView *bgView = [[UIView alloc] initWithFrame:self.frame];
    [self.superview addSubview:bgView];
    bgView.backgroundColor = [UIColor whiteColor];
    
    //------- 图标 -------//
    UIImageView *imageView = [[UIImageView alloc] init];
    [bgView addSubview:imageView];
    [imageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.mas_equalTo(imageView.superview);
        make.centerY.mas_equalTo(imageView.superview).mas_offset(-80);
        make.size.mas_equalTo(CGSizeMake(70, 70));
    }];
    
    //------- 描述 -------//
    UILabel *descLabel = [[UILabel alloc] init];
    [bgView addSubview:descLabel];
    [descLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.mas_equalTo(descLabel.superview);
        make.top.mas_equalTo(imageView.mas_bottom).mas_offset(20);
        make.height.mas_equalTo(15);
    }];
    
    //------- 重新加载button -------//
    UIButton *reloadButton = [[UIButton alloc] init];
    [bgView addSubview:reloadButton];
    [reloadButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [reloadButton setTitle:@"重新加载" forState:UIControlStateNormal];
    reloadButton.layer.borderWidth = 1;
    reloadButton.layer.borderColor = [UIColor blackColor].CGColor;
    [[reloadButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
        // 执行block回调
        if (reloadBlock) {
            reloadBlock();
        }
        // 从父视图移除
        [bgView removeFromSuperview];
    }];
    [reloadButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.mas_equalTo(reloadButton.superview);
        make.top.mas_equalTo(descLabel.mas_bottom).mas_offset(20);
        make.size.mas_equalTo(CGSizeMake(120, 30));
    }];
    
    //------- 根据type设置不同UI -------//
    switch (type) {
        case CQPlaceholderViewTypeNoNetwork: // 网络不好
        {
            NSString *path = [[NSBundle mainBundle] pathForResource:@"无网" ofType:@"png"];
            imageView.image = [UIImage imageWithContentsOfFile:path];
            descLabel.text = @"网络异常";
        }
            break;
            
        case CQPlaceholderViewTypeNoGoods: // 没商品
        {
            NSString *path = [[NSBundle mainBundle] pathForResource:@"无商品" ofType:@"png"];
            imageView.image = [UIImage imageWithContentsOfFile:path];
            descLabel.text = @"一个商品都没有";
        }
            break;
            
        case CQPlaceholderViewTypeNoComment: // 没评论
        {
            NSString *path = [[NSBundle mainBundle] pathForResource:@"沙发" ofType:@"png"];
            imageView.image = [UIImage imageWithContentsOfFile:path];
            descLabel.text = @"抢沙发!";
        }
            break;
            
        default:
            break;
    }
}

源代码在这里

希望有大佬可以抽空帮我看下,万分感谢。

回复
阅读 4k
1 个回答
✓ 已被采纳

RACsubscribeNext会copy强引用nextBlock, 所以会对reloadBlockbgView强引用

// 未成功获取数据,展示无网占位图
__weak SecondViewController *weakSelf = self;
[self.tableView showPlaceholderViewWithType:CQPlaceholderViewTypeNoNetwork reloadBlock:^{
    [weakSelf getData];
}];


__weak UIView *weakView = bgView;
[[reloadButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
    // 执行block回调
    if (reloadBlock) {
        reloadBlock();
    }
    // 从父视图移除
    [weakView removeFromSuperview];
}];
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
你知道吗?

宣传栏