在ARC机制下
接着上一篇博客,来介绍__weak引入的原因,以及__weak解决的问题,以及笔者学习__weak时的疑问.
__weak:
main.h
id test0 = [[Test alloc] init];
NSLog(@"test0 = %p",test0);
id test1 = [[Test alloc] init];
NSLog(@"test1 = %p",test1);
[test0 setObject: test1];
NSLog(@"test0 Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)test0));
NSLog(@"test1 Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)test1));
[test1 setObject: test0];
NSLog(@"test0 Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)test0));
NSLog(@"test1 Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)test1));
/*
打印例如以下:
2015-07-23 05:52:14.004 字典[2802:210763] test0 Retain count is 2
2015-07-23 05:52:14.004 字典[2802:210763] test1 Retain count is 2
原来obj 的 retainCount = 3;为何如今打印就是 2 呢?
这里就涉及到一个形參的作用域的问题,当形參超出其作用域时,就会运行 release操作
所以导致 retain--;
*/
test.h
@interface Test : NSObject{
id __strong _obj;
}
-(void) setObject:(id __strong)obj;
test.m
-(id) init{
self = [super init];
if (self ) {
return self;
}
return nil;
}
-(void) setObject:(id __strong)obj{
_obj = obj;
NSLog(@"obj = %p",obj);
NSLog(@"obj = Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)obj));
NSLog(@"_obj = Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)_obj));
/*
打印例如以下:
2015-07-23 05:52:14.003 字典[2802:210763] obj = Retain count is 3
2015-07-23 05:52:14.003 字典[2802:210763] _obj = Retain count is 3
由于obj是对形參的强引用所以导致retain++;
_obj 也对obj 强引用也导致 retain++;
*/
}
/*************************************/
所以上面的操作导致了内存泄露的问题,解决方式就是引入 __weak弱引用 将 test.h 中的 id __strong _obj;改为id __weak _obj;
(1) __weak解决的重大问题就是引用计数式内存管理中产生的”循环引用”的问题.
__autorelease:
(1) 编译器会检查方法名是否以 alloc / new /copy /mutableCopy開始,假设不是则自己主动将返回值的对象注冊到autoreleasePool中
(2) 作为alloc / new /copy /mutableCopy方法返回值取得的对象是自己生成并持有的,其它情况是取得非自己生成并持有的对象.
因此,使用附有__autoreleasesing修饰符的变量作为对象取得參数,与除alloc / new /copy /mutableCopy外其它方法的返回值取得对象全然一样,都会注入到autoreleasePool中.
id obj1 = nil;
id __strong obj = nil;
@autoreleasepool {
obj = [NSMutableArray array];
obj1 = obj;
NSLog(@"obj Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)obj));
/* 打印结果例如以下:
2015-07-23 04:09:35.927 字典[2540:183480] obj Retain count is 2
为什么reatainCount = 2 ;
原因例如以下: 介绍 array 的方法
+(id) array{
return [[NSMutableArray alloc]init];
生成的对象作为函数的返回值,编译器会自己主动将其注冊到 autoreleasePool中所以返回值为2
这里涉及到一个问题 autoreleasePool 何时释放?
}
*/
// [NSAutoreleasePool showPools];//在ARC关闭时查看POOL池内的内容 NSLog(@"%d",_objc_autoreleasePoolPrint());//在ARC机制下查看POOL池内的内容
}
NSLog(@"obj1 Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)obj1));
/*
打印例如以下:
2015-07-23 04:24:25.182 字典[2580:187987] obj1 Retain count is 1
说明autoreleasePool在出了作用域时将释放
*/