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

     */


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值