您的位置:首页 > 其它

oc学习之旅:内存管理

2013-12-20 20:40 363 查看
因为以前的代码都是使用非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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: