ARC机制之__weak,__autorelease详解

来源:互联网 发布:b1ued同志交友软件 编辑:程序博客网 时间:2024/06/08 17:05

ARC机制下

接着上一篇博客,来介绍__weak引入的原因,以及__weak解决的问题,以及笔者学习__weak时的疑问.

__weak:


main.h

id test0 = [[Testalloc] init];

   NSLog(@"test0 = %p",test0);

   id test1 = [[Testalloc] init];

   NSLog(@"test1 = %p",test1);

    [test0setObject: test1];

    NSLog(@"test0 Retain count is %ld",CFGetRetainCount((__bridgeCFTypeRef)test0));

    NSLog(@"test1 Retain count is %ld",CFGetRetainCount((__bridgeCFTypeRef)test1));

    [test1setObject: test0];

    

    NSLog(@"test0 Retain count is %ld",CFGetRetainCount((__bridgeCFTypeRef)test0));

    NSLog(@"test1 Retain count is %ld",CFGetRetainCount((__bridgeCFTypeRef)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 = [superinit];

   if (self ) {

       return self;

    }

    

    return nil;

}

-(void) setObject:(id__strong)obj{

   _obj = obj;

   NSLog(@"obj = %p",obj);

    NSLog(@"obj = Retain count is %ld",CFGetRetainCount((__bridgeCFTypeRef)obj));

    NSLog(@"_obj = Retain count is %ld",CFGetRetainCount((__bridgeCFTypeRef)_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 = [NSMutableArrayarray];

        obj1 = obj;

        NSLog(@"obj Retain count is %ld",CFGetRetainCount((__bridgeCFTypeRef)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((__bridgeCFTypeRef)obj1));

   /*

        打印如下:

            2015-07-23 04:24:25.182 字典[2580:187987] obj1 Retain count is 1

            说明autoreleasePool在出了作用域时将释放

     */


0 0
原创粉丝点击