内存管理大总结

作者: 你好自己 | 来源:发表于2016-07-20 17:21 被阅读113次

    1.自动引用计数的概念

    • 在OC中采用引用计数机制来管理对象的生命周期.
    • 在实际的项目中,我们在函数内使用一个临时的对象,通常是不需要修改它的引用计数的,只需要在函数返回前将该对象销毁即可.
    • 引用计数真正排上用场是,对象之间传递和共享数据.遵从引用计数这个规则的话,对象的生命周期的管理就完全可以交给引用计数了.

    2.内存管理/引用计数

    2.1.1 内存管理的思考方式举例

    对办公室照明设备所做的动作和对OC对象所做的动作

    对照明设备所做的动作 对OC对象所做的动作 OC方法
    开灯 生成并持有对象 alloc/copy/new/mutableCopy等方法
    需要照明 持有对象 retain方法
    不需要照明 释放对象 release方法
    关灯 废弃对象 dealloc方法

    小结:

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

    不知道的点:
    这些有关的OC内存管理的方法,实际上不包括在该语言中,而是包含在Cocoa框架中用于OSX iOS应用开发.Cocoa框架中的Foundation框架类库中的NSObject类担负内存管理的职责.OC内存管理中的alloc/retain/release/dealloc方法分别指代NSObject类的alloc类方法,retain实例方法,release实例方法和dealloc实例方法.

    针对小结的内容解释如下:

    • 自己生成对象并持有.
      举例: NSArray *arr1 = [[NSArray alloc]init]; //取得对象,并持有;- 非自己生成的对象,即使用alloc/copy/new/mutableCopy以外的方法取得的对象,也可以持有.举例:NSArray *arr2 = [NSArray array];//取得对象,但并不持有;``[arr2 retain];//自己持有对象
    • 不再需要自己持有的对象时释放.举例[arr1/arr2 release];特殊的是 针对arr1,自己生成并持有的对象,可以采用 [arr1 autorelease];,因为autorelease提供这样的功能,使对象在超出指定的生存范围时能够自动并正确的释放(调用release方法).
    • 无法释放非自己持有的对象:如果对象的引用计数已经为0,则不能再次释放,非自己持有的对象更不能释放.

    release和autorelease的区别

    release autorelease
    对象立即释放 对象不立即释放

    注册到autoreleasepool中,pool结束时自动调用release

    2.1.2 alloc/retain/release/dealloc实现

    • 在OC的对象中存有引用计数这一整数值(retainCount)
    • 调用alloc/new/copy/mutableCopy/retain方法后,引用计数值+1.
    • 调用release后,引用计数-1.
    • 引用计数为0时,调用dealloc方法废弃对象

    2.1.5 autorelease

    autorelease的具体使用方法如下:

    • 生成并持有NSAutoreleasePool对象;
    • 调用已分配对象的autorelease实例方法;
    • 废弃NSAutoreleasePool对象.
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
    id obj = [[NSObect alloc]init];
    [obj autorelease];
    [pool drain];
    

    尽管如此,当在大量产生autorelease对象时,只要不废弃NSAutoreleasePool对象,那么生成的对象就不能被释放,因此有时候会产生内存不足的现象.
    正确的做法是 把自动释放池的创建放在for循环内.代码如下:

    for(int i = 0; i< 100000;i++)
    {
    NSAutoreleasePool *pool = [][NSAutoreleasePool alloc]init];//读入图像,产生大量`autorelease`的对象.
    [pool drain];
    }
    

    在OC中,也就是Foundation框架时,无论调用哪一个对象的autorelease实例方法,实际上调用的都是NSObject类的autorelease实例方法.但是对于NSAutoreleasePool类,autorelease实例方法已被该类重载,因此运行就会报错.

    //这样写是错误滴
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
    [pool autorelease];
    

    相关文章

      网友评论

        本文标题:内存管理大总结

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