首页 > 代码库 > OC第七节——内存管理

OC第七节——内存管理

戏言:

iOS开发已经到了一个ARC时代,一般不需要我们过多的去关注内存是怎么分配,怎么管理的。很长一段时间,我也不知道内存管理是什么鬼,但如果遇到这方面的问题,却找不到解决办法确实很头疼的。So,还是静下心来,好好学习吧,毕竟内功才是体现水平。

 

1. 引用计数
            对于一块动态申请的内存,有一个人(指针)使用,就给这个内存的计数器加1,使用完成后,就给这个计数器减1,当这个内存的引用计数为0了,我们再释放他,这样,上面的问题就解决了。OC,就是使用引用计数这种方式来管理内存的。

生动的理解就是:举一个生活中的例子,我们一起去水库边烧烤,我把火点着了,当我们正在“水深火热”的烤着肉,一个电话来了,媳妇让我回家。于是,我跟你们说,你们懂的,哥要回去了,为了防止引发火灾,我要把火扑灭了。我相信,此时你们打死我的心都有。
        我们能不能想到更好的方法,我不浇灭火,又不会引起火灾?
        计数,虽然火是我生的,但我们有10个人一起用。那么,这堆火的计数为10,如果我,或者任何一个同学走了,让计数减1,变成9,8,7...这样,直到最后一个同学走,他在走之前将火灭了就好了。            这就是OC的内存管理方式,引用计数。

2.内存管理的黄金法则
            对于引用计数来说,有一套内存管理的黄金法则:
            The basic rule to apply is everything that increases the reference counter with alloc, [mutable]copy[withZone:] or retain is in charge of the corresponding [auto]release.
         只要使用了alloc/retain/copy/mutableCopy, 创建了对象
    那么就必须使用release进行释放,
        ———谁创建,谁负责释放

3.retain与retainCount
        retain,将对象进项保留操作,也就是使对象的引用计数加1。
        retainCount,打印一个对象的引用计数。

 

       DSDog*dog=[[DSDog alloc]init];
        NSLog(@"%lu",[dog retainCount]);//1 含有init,引用计数加1
        DSDog *dog2=[dog retain];
        
        NSLog(@"%lu",[dog2 retainCount]);//2  对象retain,引用计数加1
        [dog2 release];
        NSLog(@"%lu",[dog2 retainCount]);//1  release,引用计数减1
        [dog release];   // 变为0 ,销毁对象

  4.MRC和ARC
            ARC   (Automatic Reference Counting),自动引用计数,由xcode,帮我们去管理内存。
            MRC  (Manual  Reference Counting),手动引用计数,我们手动管理内存。

Xcode 5.0  以后的版本默认是ARC模式

 

工程创建的时候是ARC的,我们如果想要MRC,需要进行如下设置。
            选中工程 - target - Bulid Settings - 搜索:automatic reference counting或auto,将Objective-C Automatic Reference Counting改为NO。

技术分享

5.@property retain,assign,copy展开

5.1@property (nonatomic, retain) DSDog *dog; 用来修饰ObjC对象。

则会展开如下:
       - (void)setDog:(DSDog *)dog
        {
                if (_dog != dog)
                {
                        [_dog release];
                        _dog = [dog retain];
                }
        }
5.2 assign展开:简单数据类型

@property (nonatomic, assign) DSDog *dog;

assign是直接复制,则会展开如下:
    //简单数据类型 ,OC的内存管理对于简单的数据类型 int\float…, OC无效
    - (void)setDog:(DSDog *)dog
    {
        _dog = dog;
    }

5.3 copy展开  , 复制一份原来的对象

//copy 多用于字符串,Dict、Array
    @property (nonatomic, copy)NSString *name;
    - (void)setName:(NSString *)name
    {
        if (_name != name)
        {
            [_name release];
            _name = [name copy];
        }
    }
6.自动释放池

原理:对象接收到autorelease消息时,它会被添加到了当前的自动释放池中,当自动释放池被销毁时,会給池里所有的对象发送release消息。

ObjC提供两种方法创建自动释放池:
  方法一:使用NSAutoreleasePool来创建

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc]init];
     //这里写代码
     [pool release];
方法二:使用@autoreleasepool创建
  @autoreleasepool {
     //这里写代码
     }


7.weak:ARC新引入修饰词,可代替assign,比assign多增加一个特性
strong:ARC新引入修饰词,可代替retain
 

 

OC第七节——内存管理