iOS中内存初级管理

   1:内存的管理方式

     在ios中可能会遇见(MRC)和(ARC)的两种管理方式.

     MRC:使用的人群可能是一些老程序员,应为他们觉得比arc更安全好用.(⼈人⼯工引⽤用计数)

 ARC:是基于MRC的一种管理方式(⾃自动引⽤用计数)

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

   2:影响内存计数的方法

       下面以一个person类为演示基础

 2.1 +alloc  (引用计数加1)

 开辟内存空间,让被开辟的内存空间的引⽤用计数变为1。这是由0到1的过程

代码实现:

Person *p = [[Person alloc] init];
    
    NSLog(@"%ld",[p retainCount]);
这是的输出结果为:1

2.2 -retain (引用计数加1)
如果内存空间之前引用计数为1,retain变为2

代码如下

 Person *p = [[Person alloc] init];
    
    Person *p2 = [p retain];
    NSLog(@"%ld",[p retainCount]);

输出结果为:2

2.3 -copy 把某一内存区域的内容拷贝一份,拷贝到新的内存空间中,被拷贝的区域的引用计数不变,新内存区域的引用计数为1

Person *p = [[Person alloc] init];
    
    Person *p2 = [p retain];
    
    Person *p3 = [p2 copy];
    
    NSLog(@"%ld",[p retainCount]);

此时的输出结果为:2

2.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]);

输出结果为:1

 2.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文件中实现如下方法,(比较单一的)

- (id)copyWithZone:(NSZone *)zone
{
  
    //深拷贝
    //申请空间,创建一个对象
    Person *p = [Person allocWithZone:zone];
    //进行赋值
    p.name = self.name;
    p.age = self.age;
    p.sex = self.sex;
    //3返回刚刚生成的对象
    
    return  p;
    
    
}
在main.m中调用如下

  //深拷贝
    Teacher *teacs = [[Teacher alloc] init];
    
    
    teacs.name = @"gggggggggggggg";
    
    Teacher *t2 = [teacs copy];
    
    teacs.name = @"dddddd";
    NSLog(@"-------=%@",t2.name);
    
    NSLog(@"-------=%ld",[t2 retainCount]);
运行结果如下


综上可见,程序在执行深度拷贝的时候,不会改变copy后对象的数值.
 

  • 欢迎各位一块学习,提高逼格!
  • 也可以添加洲洲哥的微信公众号

    更多消息

    更多信iOS开发信息 请以关注洲洲哥 的微信公众号,不定期有干货推送:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值