1:内存的管理方式
在ios中可能会遇见(MRC)和(ARC)的两种管理方式.
MRC:使用的人群可能是一些老程序员,应为他们觉得比arc更安全好用.(⼈人⼯工引⽤用计数)
ARC:是基于MRC的一种管理方式(⾃自动引⽤用计数)
OC采⽤用引⽤用计数机制管理内存,当⼀一个新的引⽤用指向对象时,引⽤用计数器就递增,当去掉⼀一个引⽤用时,引⽤用计数就递减。当引⽤用计数到零时,该对象就将释放占有的资源
2:影响内存计数的方法
下面以一个person类为演示基础
2.1 +alloc (引用计数加1)
开辟内存空间,让被开辟的内存空间的引⽤用计数变为1。这是由0到1的过程
代码实现:
这是的输出结果为:1Person *p = [[Person alloc] init]; NSLog(@"%ld",[p retainCount]);
2.2 -retain (引用计数加1)
如果内存空间之前引用计数为1,retain变为2代码如下
Person *p = [[Person alloc] init]; Person *p2 = [p retain]; NSLog(@"%ld",[p retainCount]);
输出结果为:22.3 -copy 把某一内存区域的内容拷贝一份,拷贝到新的内存空间中,被拷贝的区域的引用计数不变,新内存区域的引用计数为1
Person *p = [[Person alloc] init]; Person *p2 = [p retain]; Person *p3 = [p2 copy]; NSLog(@"%ld",[p retainCount]);
此时的输出结果为:22.4 -release (引用计数减1) 如果之前的引用计数为1,release之后变为0,内存会被系统回收.
Person *p = [[Person alloc] init]; Person *p2 = [p retain]; Person *p3 = [p2 copy]; [p release]; NSLog(@"%ld",[p retainCount]);
输出结果为:12.5 -dealloc 当引用计数为0的时候,由对象自动调用
调试方法
2.5.1 首先在对应类的.m文件中写上
-(void)dealloc { NSLog(@"引用计数为0,系统自动调用"); [super dealloc]; }
然后在main.m中调用Person *p = [[Person alloc] init]; Person *p2 = [p retain]; Person *p3 = [p2 copy]; [p release]; [p release]; NSLog(@"%ld",[p retainCount]);
应为在第一次使用 p release是p的应用计数为2,所有用两次release才能吧引用计数调成0,才能出现效果
2.6 -autorelease,未来的某一时刻引用计数减1
在autorelease中所有的引用都是在栈区存放,所以在调用的时候返回的结果是,先进后出,后进先出
3:内存管理原则
引用计数和增加相等,当引用计数为0的时候,该快内存则不再被使用.
在一块代码内,增加和减少的次数要相等.
4:Copy的实现
在实现copy的时候有两种过程,一个是深拷贝和浅拷贝
4.1浅拷贝
如果指针*p指向了A内存的a地址,*p2也指向了A内存中的a地址,两个指向同一个地址,如果*p指向的内容改变,则*p2也改变.
©代码如下:在实现copy动作的时候用实现协议<nscopying>
©在对应类的.m文件中实现该方法
- (id)copyWithZone:(NSZone *)zone { //浅拷贝 return [self retain]; }
4.2深拷贝 在原有的基础上把对用的区域拷贝到另外一块内存中实现代码如下 先实现协议<nscopying>
在对应.m文件中实现如下方法,(比较单一的)
在main.m中调用如下- (id)copyWithZone:(NSZone *)zone { //深拷贝 //申请空间,创建一个对象 Person *p = [Person allocWithZone:zone]; //进行赋值 p.name = self.name; p.age = self.age; p.sex = self.sex; //3返回刚刚生成的对象 return p; }
运行结果如下//深拷贝 Teacher *teacs = [[Teacher alloc] init]; teacs.name = @"gggggggggggggg"; Teacher *t2 = [teacs copy]; teacs.name = @"dddddd"; NSLog(@"-------=%@",t2.name); NSLog(@"-------=%ld",[t2 retainCount]);
综上可见,程序在执行深度拷贝的时候,不会改变copy后对象的数值.
- 欢迎各位一块学习,提高逼格!
也可以添加洲洲哥的微信公众号
更多消息
更多信iOS开发信息 请以关注洲洲哥 的微信公众号,不定期有干货推送: