强引用,弱引用

本文是看别人的文章,结合自己的想法又整理了下,自己理解的也不是很深,如有问题请随时指导。


OC的内存管理是通过“引用计数器”来实现的。一个对象的生命周期取决于它是否还被其他对象引用(是否retainCount=0)。但在有些情况下,我们并不希望对象的销毁时间是被其他对象引用来决定,而是这个对象本该是什么时候销毁就是什么时候销毁,这时,就有了强引用弱引用 的引入。

  • 强引用:当前对象被其他对象引用时,会执行retain操作,引用计数器+1。当retainCount=0时,该对象才会被销毁。因为我们要进行对象的内存管理,所以这是默认的引用方式。(默认是强引用)
  • 弱引用:当前对象的生命周期不是由其他对象引用限制,它本该什么时候销毁就什么时候销毁,即使它的引用没断,但是当它的生命周期到了时就会被销毁。

    retain、strong、assign、weak
    在定义属性时,若声明为retain类型的,就是强引用;若声明为assign类型的,就是弱引用。后来内存管理都是由ARC来完成后,若是强引用,则声明为Strong;若是弱引用,则声明为weak。

  • atomic:默认是有该属性的,这个属性是为了保证程序在多线程情况下,编译器会自动生成一些互斥加锁代码,避免该变量的读写不同步问题。
  • nonatomic:如果该对象无需考虑多线程的情况,请加入这个属性,这样会让编译器少生成一些互斥加锁代码,可以提高效率。
  • strong:强引用,也是我们通常说的引用,其存亡直接决定了所指向对象的存亡,如果不存在一个对象的引用,并且此对象不再显示在列表中,则此对象会被从内存中释放。
  • weak:弱引用,不决定对象的存亡,即使一个对象被持有无数个弱引用,只要没强引用指向它,那么还是会被清除。
  • 使用assign:对基本数据类型(NSInteger, CGFloat)和C数据类型(int, float, double, char,等等)
  • 使用copy:对NSString
  • 使用retain(strong):对其他NSObject和其子类

    所以,retain和strong是一致的(声明为强引用);assign和weak是基本一致的(声明为弱引用)。之所以说它俩是基本一致是因为它俩还是有所不同的,weak严格的说应当叫 归零弱引用 ,即当对象被销毁后,会自动的把它的指针置nil,这样可以防止野指针错误。而assign销毁对象后不会把该对象的指针置nil,对象已经销毁,但指针还指向它,这就成了野指针,这是比较危险的。

避免强弱引用循环的僵局
默认的引用方式是强引用,但上面说了有时我们还是得用弱引用,下面的情况下会使用弱引用:
A对象强引用了B对象,B对象也强引用了A对象。因为都是强引用,要想销毁A或B必须要对方先销毁,自己才能销毁,这样就会造成无法释放的问题。为了避免出现这种情况,就应该有一个对象“示弱”,使其为“弱引用”。
比较常见的情况有:
1. 视图中的父子视图之间的引用(这种情况我没遇见过)。
2. 在block块回调的时候,定义的时候用了该属性,在回调代码块里又用了该属性,这样会造成引用循环,在非ARC情况下可以用__block,在ARC情况下可以用__weak,如下

//在使用风火轮的第三方的时候,遇到过这个,block的回调里必须用弱引用。
__weak typeof(self) weakSelf = self;
    [weakSelf.tableview addLegendHeaderWithRefreshingBlock:^{
        weakSelf.tableview.header.hidden = NO;
        [weakSelf.tableview.header beginRefreshing];

    }];

关于copy
retain和strong都是指针拷贝(浅拷贝)。当有其他对象引用当前对象时,会拷贝一份当前对象的地址,这样它就也指向当前对象了。所以,还是同一个对象,只是retainCount+1;
而copy则是内容拷贝(深拷贝)。是实实在在的拷贝一个新的对象,拷贝了它的内存内容,成为一个新的对象(retainCount=1)。
深拷贝(mutableCopy)就是内容拷贝。
浅拷贝(copy)就是指针拷贝。
在OC中,若要进行对象的拷贝,则该对象所属的类必须遵守NSCopying和NSMutableCopy协议,并重写copyWithZone和mutableCopyWithZone方法。而系统原生类,之所以可以直接进行拷贝是因为它已经帮我们自动做了这些事。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值