IOS--OC--LessonMermory 内存管理


一 内存管理介绍

1.内存管理的重要:应用的运行都需要内存 ,如果合理管理内存 会造成应用程序崩溃 ,也就是闪退(crash)影响我们使用.

2.内存管理的问题:

① 内存溢出:IOS 给每个程序运行都设定了 一定的内存,如果超过了这个限定,便是溢出,造成 Crash;

②野指针:指针指向了 僵尸对象°,

注:僵尸对象:对象内存空间已经被回收,但指针仍操作这个空间;

3.内存管理的方式:

垃圾回收: gc  (Garbage Collector) 程序员只需要开辟内存空间,不需要⽤用代码显⽰示地释放,系统来判断哪些空间不再被使⽤用,并回收这些内存空间,以便再次分配。整个回收的过程不需要写任何代码,由系统⾃自动完成垃圾回收。Java开发中⼀一直使⽤用的就是垃圾回收技术。

缺点: gc 有不稳定性,回收无规律可循,不会立刻回收,也可能到结束也不会回收,所以在 Java 开发中会加入一个指令 强制 gc 运行;

 ②人工引用计数 :MRC (Maual Reference Count)  有程序员自己通过引用计数去管理释放和开辟空间  相对 gc 灵活, 可在需要时释放

缺点:因为是通过程序代码,所以对程序员的要求较高,需熟练掌握内存管理机制;

③自动引用计数: ARC( Automatic Reference Count) 可以认为是 IOS5.0的编译器特征,它允许用户开辟空间,但是不需要释放,编译器会帮程序员默认加了释放代码  但这个不是垃圾回收 本质还是 MRC

缺点: 不及时 ;


-------------------------------------------------------Nyx------------------------------------------------------------


二 内存管理机制

1.引用计数器: retainCount  占4个字节, 占字符 %lu,

2.定义:当一个新的引⽤指向对象时,引用计数器就递增,当去掉一个引用时,引⽤计数就递减。当引⽤计数到零时,该对象就将释放占有的资源

3.影响应用的方法:

①递增,:(alloc; copy; new; retain; ) 将引用计数+1

{

<1> alloc : 开辟空间,并将开辟空间的引用计数由0 -->1,

例:  Person*person = [[Personalloc ] init];/ /这时候引用计数变成了 1

<2> retain :引用计数加1  在之前的引用 计数上加一个,如果之前是1  那么retain 之后 就是2;

例:

 [person retain ];

 NSLog(@"%lu",person.retainCount);

在控制台中输出为2.

<3> new :类似 alloc ]init ,既能申请空间 并将空间初始化,然后将 retainCount 由0变成1;

例:

    Person *person7 = [Personnew];
    person7.name = @"lei";
    NSLog(@"%lu",person7.retainCount);

}


Copy 比较特殊 下面会单独写一个


② 递减:(release,autorelease) 就是对 引用计数- 1

{

<1> release : 对一个对象的计数器 - 1 减到0 对象就会从内存中释放掉 (dealloc);

[person retain ];//1
[per release];//0 自动释放 dealloc;

<2>@autorelease:{

有大括号 才是完整的 这一个自动释放池 如果想用 又想快速释放 可以讲@ autorelease {}写在 for 循环的第一层,

}

第二种自动释放池

 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
    Person *person3= [[Personalloc]init ];
    person3.name = @"wang";
 
    [pool release];

注:紫色的两行构成一个完整的释放池 ,不过不推荐用 ,第一种更方便

<3>  dealloc :(继承⾃自⽗父类的⽅方法,当对象引⽤计数为0的时候,由对象⾃动调⽤用)

我们为了看出 是否到0   可以在. m 里面写一个代码 当计数为0时 就跳入这个代码

例: -(void)dealloc{

NSLog(@“%@被销毁了”,self);

[super dealloc];     //  这个代码 是必须要有额  而且在大括号代码里的最下面

}


2.autorelease 和 release 的区别

   1.autorelease 相比 release 也是对引用计数器 执行-1操作,不过 autorelease 不是立即释放-1 而是在未来的某个时间

    2.autorelease 的实质: 对一个对象使用 autorelease 操作,这个对象的引用计数不会立即-1,对象会被放在自动释放池里面,等这个池子结束之后,会对对象的引用计数依次-1







-------------------------------------------------------Nyx------------------------------------------------------------

三   Copy :

1.定义把某⼀内存区域的内容拷⻉一份,拷⻉到新的内存空间⾥里去,被拷贝区域的引⽤用计数不变,新的内存区域的引⽤用计数为1


注意:对象使用 copy 的前提 ,这个类遵循了 NSCopying 协议 而且必须实现协议内的方法

例:在. h 文件中

@interface Person : NSObject <NSCopying>    // Object 后面 跟了 <NSCopying>, 这就协议遵守好了

在. m 中
① 浅拷贝: 单纯拷贝指针(也就是地址,打出来的是 一串数字)

-(id)copyWithZone:(NSZone *)zone{


return [self retain];


}

② 深拷贝: 会从新开辟一个空间  复制原来的内容,返回一个新的对象,但是所占空间大小相同, 可以理解为 A 被完整复制 ,但是换了地址 ,

-(id)copyWithZone:(NSZone *)zone{

 Person *p = [[Person allocWithZone:zone]init];

    p.name =@"123";
    
    return p;

}




-------------------------------------------------------Nyx------------------------------------------------------------







    ❀      内存管理小知识     ❀

1.谁 alloc  谁 release ,用了 就释放 哪怕就一次;

2. 为了方便可以定义带参宏

例:#define RELEASE_SAFE(_point) [_point release];_point = nil;

     宏         下面要用的新名字            要代替的方法格式,用分号隔开

3.使用了alloc、retain或者copy让内存的引用计数增加了,就需要使用release或者autorelease让内存的引用计数减少。在一段代码内,增加和减少的次数要相等。

4. 如果是像生成自己的副本 ,对象可以使用 copy  ,但是一定要遵守 NSCopying 的 协议哟 \(≧▽≦)/


5.设置内存管理之前要记得将系统的 ARC 关闭







 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值