oc学习之旅:内存管理

因为以前的代码都是使用非ARC(手动管理),而ARC还不太完善,因此学习非ARC模式还是有必要的。

在用非ARC模式

引用计数器概念

oc中,在oc定义的类型都设计有一个引用计数器retainCount。而oc中的引用分两种,一种是强引用retain(对应ARC中的strong),另一种是弱引用assign(对应ARC中weak)。

有趣的是,c中的数据类型都是弱引用,assign。


强引用弱引用都是引用。类似于c++中的&b = a。内存地址都是指向被引用的内存地址,唯一不同的地方是oc中的弱引用与c中的指针类似,

c中如果p1,p2同时指向了同一块内存空间p

即 int a = 0,*p = &a,*p1 = p,*p2 = p;

如果当中一个指针释放掉了释放掉了(如free p1),其他指针瞬时间就成为野指针,不能用了。

oc中的弱引用是直接用等号,如 NSMutableString  *str1 = str;如果str改变了,str1也一起改变,因为它是一个引用对象,与被引用对象指向同一块内存空间。如果str被销毁了,str1也成为了“野指针”。也是不能使用的

        NSMutableString *str = [[NSMutableStringalloc]initWithString:@"111"];

       NSString *str1 = str;

        [strappendString:@"sss"];

       NSLog(@"%@",str1);//打印   111sss


        NSMutableString *str = [[NSMutableStringalloc]initWithString:@"111"];

       NSString *str1 = str;

        [strappendString:@"sss"];

        [strrelease];

       NSLog(@"%@",str1);//没有东西打印,因为str已经被释放掉了,str1也不存在了


oc中的强引用与弱引用一样,都是与被引用对象共享同一块内存地址。与弱引用不同的地方是,强引用增加了引用计数retainCount。当str1强引用了str,retainCount计数器会加1,而str release(相当于 free str)后,retainCount会减1,直到retainCount减为0时候,系统才会自动调用dealloc析构函数,把内存释放掉。就是说str1强引用了str,str释放掉了,str1仍然能使用那块内存。

        NSMutableString *str = [[NSMutableStringalloc]initWithString:@"111"];

       NSMutableString *str1 = [strretain];

        [strappendString:@"sss"];

        [strrelease];

       NSLog(@"%@",str1);//打印的是111sss

有趣的是,c中的类型虽然使用弱引用assign与weak修饰,但是并不是一个引用,大概是因为oc中完全兼容c语言,所以在这方面没有改,所以assign有两个含义,一个是继续沿用c语言的那套数据类型,另一个是oc中得弱引用。

举例说明,我创建了一个Person类,里面实现了一个整形a的getter与setter函数。然后实例化了一个对象p后用a去“弱引用”b,再改变b的值,p.a不变.

在Person.h中

@property (nonatomic,assign)int a;

main中

        

Person *p = [[Personalloc]init];

int b  =0;

        p.a = b;

        b=1;

       NSLog(@"%d",p.a);//结果为0

因为c中的大多数都是存放在常量区中,b指向了另一个常量区中的1,只是c中不像oc中那样a随着b的指向而改变,因此不能称为弱引用。


        Person *p = [[Personalloc]init];

        [p.arraddObject:@"abc"];

       NSLog(@"p.Arr is %@",p.arr);

        

        NSMutableArray *arr = [NSMutableArrayarrayWithObjects:@"1",@"2",@"3",nil];

        

        p.arr = arr;

        [p.arraddObject:@"wahaha"];

       NSLog(@"arr is %@",arr);

        

        NSMutableArray *arr1 = [[NSMutableArrayalloc]init];

        //对添加到的对象引用计数+1

        [arr1addObject:p];

        [prelease];

        NSLog(@"%ld",p.retainCount);

        

        //当数组被释放或调用remove方法时他会对数组当中的所有对象做一次release操作

        [arr1release];

Person.h中

{

    NSMutableArray *_arr;

}

@property(nonatomic ,retain)NSMutableArray *arr;

因为使用了retain强引用,所以当析构时候会计数器会减1

Person.m中

-(void)dealloc

{

    NSLog(@"dealloc");

   self.arr =nil;,//相当于arr = [nil retain]; 又相当于arr release; 和  arr = nil;

    [superdealloc];

}

-(id)init

{

   if (self = [superinit]) {

       _arr = [[NSMutableArrayalloc]init];

        NSLog(@"%ld",_arr.retainCount);//结果为1

        

    }

 

 return self;

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值