进击的KFC:OC(第九天):内存管理初级

⼀、内存管理介绍
内存的问题体现在两个方面:内存溢出,野指针异常
内存管理的⽅式:
垃圾回收(gc): 在OSX系统中用到
MRC(Manual Reference Count) // 手动引用计数
ARC(Auto Reference Count):自动引用计数
在ios开发过程中,用到的是引用计数的方法

⼆、内存管理机制
OC采⽤引⽤计数机制管理内存,当⼀个新的引⽤指向对象时,引⽤计数器就递增,当去掉⼀个引⽤时,引⽤计数就递减。当引⽤计数到零时,该对象就将释放占有的资源。

影响引⽤计数的⽅法:
+alloc : 开辟内存空间,让被开辟的内存空间的引⽤计数变为1。
这是由0到1的过程。

-retain: 引⽤计数加1,如果内存空间之前引⽤计数为1,ratain之后变为2,如果引⽤计数是5,retain之后变为6
-copy : 把某⼀内存区域的内容拷⻉⼀份,拷⻉到新的内存空间⾥
去,被拷⻉区域的引⽤计数不变,新的内存区域的引⽤计数为1。

-release : 引⽤计数减1,如果内存空间之前引⽤计数为4,release之后变为3,如果之前引⽤计数为1,release之后变为0,内存被系统回收。

-autorelease : 未来的某⼀时刻引⽤计数减1。如果内存之前引⽤计数为4,autorelease之后仍然为4,未来某个时刻会变为3。它是需要依托一个叫autoreleasepool自动释放池的,当调用autorelease的对像出了释放池的时候,释放池会给这些对象发送一个release的消息.

三、内存管理原则
引⽤计数的增加和减少相等,当引⽤计数降为0之后,不应该再使⽤这块内存空间。
凡是使⽤了alloc、retain或者copy让内存的引⽤计数增加了,就需要使⽤release或者autorelease让内存的引⽤计数减少。在⼀段代码内,增加和减少的次数要相等。

四、copy
-跟retain不同,⼀个对象想要copy,⽣成⾃⼰的副本,需要实现NSCopying协议,定义copy的细节(如何copy)。如果类没有接受NSCopying协议⽽给对象发送copy消息,会引起crash。

Person类copy⽅法的实现:
第一步:
Person.h⽂件
@interface Person : NSObject<NSCopying>
@property(nonatomic, retain)NSString *name;
@property(nonatomic, assign)int age;
@end

第二步:
Person.m⽂件
@implementation Person
- (id)copyWithZone:(NSZone *)zone{
 Person *p = [[Person allocWithZone:zone]init];
 p.age = self.age;
 p.name = self.name;
 return p;
// copy方法 对引用计数的影响,要看你是怎么想的
//分为三种拷贝方法:
     // 1.伪拷贝:拷贝完还是那一个对象(直接返回)
     //return self; // 调用时 计数不变  ,

     // 2.浅拷贝:
     // 拷贝后,有两个对象,但是他们的值是同一个值,引用计数变 化,被拷贝的对象不变,拷贝出来的对象从0-1
     // Person *p =[[Person alloc]initWitnName:_name age:_age];
     // return p;

    // 3.深拷贝: 拷贝出新的对象, 并且 对象的值也重新拷贝一份,再赋值
    // 对字符串进行拷贝 拷贝的结果 要看字符串这个类如何实现的拷贝方法 对不可变字符串的拷贝相当于直接retain
    // 对可变字符串 拷贝时,就是真拷贝了一个新的出来
    //NSString *name = [_name copy];
    //Person *p = [[Person alloc] initWitnName:name age:_age];
    //return p;
    }

第三步:
main.m⽂件
Person *p = [[Person alloc]init];
p.name = @”张三”;
p.age = 20;
Person *p2 = [p copy];
p2是p的副本。p2.name与p.name⼀样。p2.age与p.age⼀样。

总结:
1.OC借助引⽤计数机制去管理内存,凡是使⽤了alloc、copy、retain等⽅法,增加了引⽤计数,就要使⽤release和autorelease减少引⽤计数,引⽤计数为0的时候,对象所占的内存,被系统回收。

2.autorelease是未来某个时间(出autoreleasepool)引⽤减⼀,不是即时的。

3.不是任何对象都可以接收copy消息,只有接受了NSCopying协议的对象才能接收copy消息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值