• 第29条:理解引用计数


    自动引用计数(Automatic Reference Counting, ARC

    垃圾收集器:

    从Mac OS X 10.8开始,“垃圾收集器”(gargae collector)已经正式废弃了。

    每个对象都有个计数器,用以表示当前有多少个事物想令此对象继续存活下去。叫做“保留计数”(retain count),也可以叫“引用计数”(reference count)。

    由三个方法操作计数器

    reatain 递增

    release 递减

    autorelease 递减,自动释放池(autorelease pool,第34条) 

    查看保留计数的方法:retainCount, 不推荐使用。

    对象创建出来时,其保留计数至少为1。

    当保留计数为零时,对象就回收了(deallocated),也就是说,系统会将其占用的内存标记为“可重用”(reuse)。

    内存在“解除分配”(deallocated)之后,只是放回“可用内存池”(avaiable pool)。如果该内存没有覆写,那么对象仍然有效,这时程序不会崩溃。

    为避免在不经意间使用了无效对象,一般调用完饭release之后都会清空指针。这时就能保证不会出现可能指向无效对象的指针,这种指针通常称为“悬挂指针”(dangling pointer,野指针)。

    例:

      [xxxx release];

      xxxx = nil;

    对象如果持有指向其他对象的强引用(strong reference),那么前者就“拥有”(own)后者。

    引用的“根对象”

    MAC OS X应用程序中,NSApplication对象

    iOS应用程序中,UIApplication对象。

    两者都应用程序启动时创建的单例。

    属性存取方法中的内存管理

    例:

    -(void)setFoo:(id)foo {

      // [foo retain]; // 先保留新值

      // [_foo release]; // 再释放旧值

      // _foo = foo; // 更新实例变量,令其指向新值

      [_foo release];

      _foo = [foo retain];

    }

    顺序很重要。

    假如还未保留新值就先把旧值释放了,而且两个值又指向同一个对象,那么,先执行的release操作就可能导致系统将此对象永久回收。而后续的retain操作则无法令这个已经彻底回收的对象复生,于是实例变量成了悬挂指针。

    自动释放池:

    autorelease,此方法会在稍后递减计数,通常是在下一次“事件循环”(event loop)时递减,不过也可能执行地更早些(自己创建的自动释放池)。

    autorelease能延长对象生命期,使其在跨越方法调用边界后依然可以在存活一段时间。

    一般用于方法中返回对象时。

    例:

    -(NSString *)stringValue {

      NSString *str = [NSString alloc]initWithFormat:@"%@",self];

      retrun [str autorelease];

    }

    保留环(retain cycle):

    循环引用,无法释放

    1、通常采用“弱引用”(weak reference,参见第33条)

    2、或者从外界命令(nil循环中的某个对象不再保留另外一个对象。

    这两种方法都可以打破保留环,从而避免内存泄漏。

  • 相关阅读:
    C++设计模式-Bridge桥接模式
    解决VS2010打开Web页面时经常由于内存较低而导致VS2010自动关闭的问题
    Js继承小结
    MAC上的包管理利器
    Objective-C的hook方案(一): Method Swizzling
    OleContainer操作Excel以二进制方式读写数据库
    复制文件时,如何显示进度条(使用TFileStream一点一点读,或者使用BlockRead,并插入application.ProcessMessages)
    ADO异步查询显示进度条
    D2010 RTTI + Attribute 简单实现ORM
    Delphi默认窗体随想
  • 原文地址:https://www.cnblogs.com/Pikdays/p/5742635.html
Copyright © 2020-2023  润新知