因为以前的代码都是使用非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也不存在了
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;
}