内存管理与引用计数

作者: wright | 来源:发表于2015-03-30 14:15 被阅读218次

引用计数式内存管理的思考方式

引用计数式的内存管理方式主要涉及四个操作:生成对象,持有对象,释放对象,废弃对象。

  • 内存管理的思考方式

    • 自己生成的对象,自己持有
    • 非自己生成的对象,自己也能持有
    • 不再需要自己持有的对象时释放
    • 非自己持有的对象无法释放

与oc中方法对应如下:

+对象操作                       +Oc方法
生成并持有对象             alloc/new/copy/mutablecopy等方法
持有对象                        retain方法
释放对象                        release方法
废弃对象                        dealloc方法
  • 自己生成的对象,自己持有

使用alloc, new, copy, mutablecopy开头的方法意味着自己生成的对象自己持有

注:命名要符合驼峰命名法。

  • 非自己生成的对象,自己也能持有

通过retain方法,非自己生成的对象也可以持有对象了。

  • 不再需要自己持有的对象时释放

自己持有的对象,一旦不再需要,持有者有义务释放该对象。释放使用release方法。

使用autorelease方法可以使取得的对象存在,但是自己不持有对象。

  • 无法释放非自己持有的对象

释放非自己持有的对象会造成程序的崩溃。

GNUSTEP和APPLE中alloc/retain/release/dealloc的实现

在申请内存的时候,会在内存头部之前申请一块内存用来保存引用计数。然后分别在不同的操作的时候对这一引用计数值进行判断并作相应调整。总结如下:

1.调用alloc或是retain方法后,引用计数值加1。
2.调用release之后,引用计数值减1
3.引用计数值为0时,调用delloc方法废弃对象

苹果在实现上述方式时没有使用内存头部管理引用计数,而是使用采用了散列表管理引用计数

autorelease

自动释放--autorelease

aurorelease就是自动释放,类似于c语言中的自动变量。

autorelease的具体使用方法:

1,生成并持有NSAutoreleasePool对象
2,调用已分配对象的autorelease实例方法
3,废弃NSAutoreleasePool对象

在Cocoa框架中,相当于程序主循环的NSRunloop或者在其他程序可运行的地方,对NSAutoreleasePool对象进行生成,持有和废弃处理。

ARC规则

所有权修饰符:

  • _strong修饰符
  • _weak修饰符
  • _unsafe_unretained修饰符
  • _autoreleasing修饰符

_strong修饰符

_strong修饰符是id类型和对象类型默认的所有权修饰符。附有_strong修饰符的变量在超出其变量作用域时,释放其被赋予的对象。_strong修饰符表示对对象的“强引用”,持有强引用的变量在超出其作用域时被放弃,随着强引用的失效,引用的对象会随之释放。通过_strong修饰符,不必再次键入retain或者release,就完美的满足了“引用计数式内存管理的思考方式”。

注:id类型和对象类型的所有权修饰符默认为_strong修饰符。

_weak修饰符

如果仅使用_strong修饰符会造成“循环引用”的问题,这个时候就用到了_weak。带有_weak修饰符的变量不持有对象,所以在超出其变量作用域时,对象即被释放。_weak的另一个优点是,在持有某对象的弱引用时,若该对象被释放,则此弱引用将自动失效且处于nil被赋值状态。

_unsafe_unretained修饰符

在ios5以下版本中无法使用_weak,所以_unsafe_unretained成为替代品。但是_unsafe_unretained不保证最后的对象被释放,且处于nil被赋值状态。所以赋值给附有_unsafe_unretained修饰符变量的对象在使用时,要确保它存在。

_autoreleasing修饰符

在ARC有效时,用“@autoreleasepool块”来代替“NSAutoreleasePool”。

编译器会检查方法名是否以alloc/new/copy/mutableCopy开始,如果不是则自动将返回值的对象注册到autoreleasepool(注:init返回值的对象不注册到autoreleasepool)。在使用附有_weak修饰符的变量时必须访问注册到autoreleasepool的对象,因为_weak修饰符持有对象的弱引用,在访问引用对象的过程中,该对象可能被丢弃,所以把要访问的对象注册到autoreleasepool中,那么在@autoreleasepool结束之前多能确保该对象存在。

属性

      属性声明的属性                       所有权修饰符
        assign                          _unsafe_unretained
        copy                            _strong
        retain                          _strong
        strong                          _strong
        unsafe_unretained               _unsafe_unretained
        weak                            _weak

其中:
assign:一般基本变量用该属性声明,eg:int BOOL

copy:声明的变量是拷贝赋值源所生成的对象

retain和strong表示意思相同

strong:属性所声明的变量将成为对象的持有者

unsafe_unretained:ios5之前的系统用该属性代替weak

关于ARC认识很好的博文,一个系列,值得一读。

相关文章

  • Obj-C高级编程--内存管理

    自动引用计数 自动引用计数:指内存管理中对引用采取自动计数的技术。 内存管理/引用计数 持有对象引起引用计数加...

  • Swift进阶 05:内存管理 & Runtime

    本文主要介绍Swift中的内存管理,涉及引用计数、弱引用、强引用、循环引用与Runtime等。 内存管理-强引用 ...

  • 内存管理与自动引用计数—第一日

    自动引用计数 1.1 什么是自动引用计数 内存管理中对引用采用自动计数的计数 1.2 内存管理/引用计数 这一张举...

  • iOS内存管理1:引用计数

    iOS内存管理1:引用计数 引用计数: Objecttive-C使用引用计数来进行内存管理。然后,引用计数其实是不...

  • Effective Objective-C 2.0笔记(四)

    第五章 内存管理 第29条:理解引用计数 OC使用引用计数管理内存,引用计数机制通过递增递减的计数器来管理内存。对...

  • EffectiveObjective-C2.0 笔记 - 第五部

    5 内存管理 5.1 理解引用计数 1、引用计数 Objective-C 语言使用引用计数来管理内存,每个对象都有...

  • Effective Objective-C 2.0 总结(五)

    内存管理 第 29 条:理解引用计数 引用计数工作原理 Objective-C 语言使用引用计数来管理内存,每个对...

  • Objective-C高级编程之内存管理篇

    iOS的内存管理是采用引用计数的方式,引用计数分为手动引用计数和自动引用计数(ARC)。前者要求开发者手动管理内存...

  • 目录

    第1章自动引用计数 1.1什么是自动引用计数 1.2内存管理/引用计数 1.2.1概要1.2.2内存管理的思考方式...

  • 读《Objective-C高级编程..》笔记

    第一章、自动引用计数 1、内存管理/引用计数 OC中通过引用计数来进行内存管理(其他的内存管理方式有垃圾回收等) ...

网友评论

    本文标题:内存管理与引用计数

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