美文网首页
常见内存泄漏情况梳理

常见内存泄漏情况梳理

作者: 夜明u | 来源:发表于2017-03-10 23:28 被阅读0次

    一、循环引用,

    以两个实例为例,循环引用产生于两个实例都强引用的对方,而两个实例的释放都依赖于对方的释放,最终都无法释放。

    1.delegate修饰成了strong,

    2.block引起。

    block引起循环引用要注意,block也是一个对象,当block被对象A持有,在block代码块中直接调用对象A相当于block对象强引用了对象A。举两个第三方库对比看看,

    Masonry:

    [buttonA mas_makeConstraints:^(MASConstraintMaker*make){

    make.width.equalTo(@100);

    make.height.equalTo(@100);

    make.left.equalTo(self.view.mas_left);

    make.top.equalTo(self.view.mas_top);

    }];

    这里直接用self是因为这个block没有被持有,执行完就被释放了,看源码可知

    -(NSArray*)mas_makeConstraints:(void(^)(MASConstraintMaker*))block{

    self.translatesAutoresizingMaskIntoConstraints=NO;

    MASConstraintMaker*constraintMaker=[[MASConstraintMakeralloc]initWithView:self];

    block(constraintMaker);

    return[constraintMakerinstall];

    }

    AFNetworking:

    AFNetworking源码可知,其内部使用了嵌套结构,以保证在回调的时候不会已经被释放,类似这样

    __weakNSObject*weakSelf =self;

    void(^block)(void) = ^{

    //NSLog(@"b_name = %@",b_name);

    __strongNSObject*strongSelf = weakSelf;

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1*NSEC_PER_SEC)),dispatch_get_main_queue(), ^{

    NSLog(@"b_name = %@",strongSelf);//此处即为回调

    });

    };

    block();

    二、NSTimer

    NSTimer *tt  =[NSTimerscheduledTimerWithTimeInterval:1target:self selector:@selector(timerMethod:)userInfo:nilrepeats:YES];

    [tt fire];

    这种方式直接创建的timer,将target设置成self,会导致之self的释放依赖于timer的终止。可以用weakSelf代替,timer还是要主动invalidate。

    三、UIImage加载图片

    [UIImage imageNamed:@""]的方式当加载时会缓存图片,图片如果使用频繁可以用这种,否则推荐使用imageWithContentsOfFile。

    四、C对象的创建和释放

    例如CoreFoundation对象 : 函数中用create\new\copy\retain产生的对象, 不用的时候需要调用CFRelease或者其他release函数,将其释放掉。使用一些ffmpeg,opencv2等底层第三方的时候尤其要注意这一点。

    相关文章

      网友评论

          本文标题:常见内存泄漏情况梳理

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