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;
}
在用非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;
}
相关文章推荐
- OC学习篇之---内存管理介绍和使用
- 黑马程序员---学习笔记23:OC基础(10)内存管理
- 黑马程序员 OC------内存管理学习
- 黑马程序员--学习OC加强内存管理
- OC学习那些事:内存管理
- 黑马程序员---OC学习笔记之集合对象的内存管理
- OC学习之Objective-C的内存管理
- OC学习篇之---内存管理介绍和使用
- Ryan的OC学习总结-----7 内存管理
- OC语言之学习篇——02——内存管理
- -OC学习之内存管理与ARC
- OC学习笔记六 内存管理(autorelease)
- OC学习篇之-----内存管理
- oc学习之旅:内存管理2修改数组为非ARC版本
- oc学习之旅:内存管理,文件操作流程
- 黑马程序员——OC的内存管理学习小结
- OC学习笔记之OC对象的内存管理
- 【IOS 开发学习总结-OC-24】★★★objective-c——内存管理
- 黑马程序员学习笔记_OC之内存管理1