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

         */


  • 相关阅读:
    PHP发送邮件(php100视频后笔记)
    简单页面访问统计
    怎样制作RSS源
    r给自己网站/博客制作安卓应用程序
    反射简单概念
    笔记本
    使用IHttpModule实现简单的页面重映射Url
    工厂方法模式与抽象工厂模式的区别
    安装TFS2010实际体验
    限定登录失败次数,超过指定次数就限制登录一段时间
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/6962769.html
Copyright © 2020-2023  润新知