ARC机制之__weak,__autorelease具体解释

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在出了作用域时将释放

     */


原文地址:https://www.cnblogs.com/wgwyanfs/p/6962769.html