objective-c中的strong和weak属性(一)

在使用ARC的情况下, strong类型的变量会对ARC中的count做+1的动作,在ARC执行自动release的时候会检查count,当ARC发现count大于0,就不会释放资源, 而weak不会使count增加,weak只是简单的把源对象的指针拿过来用,不影响ARC的release动作, 在使用weak的时候要确保使用期间源对象是有效的, 也就是说必须在源对象的生命周期内使用weak引用,否则的话会导致程序异常.下面用代码说明一下weak和strong.
例子1:

- (void)viewDidLoad

{ //作用域1

    [superviewDidLoad];

    //NSString * strongStr; 等同于NSString * __strong strongStr;

    NSString *__weak weakStr;

    {//作用域2

        

        NSString *__strong strongStr;

        

        {//作用域3

            //NSString* oriStr 等同于NSString* __strong oriStr

            NSString* oriStr = [[NSStringalloc] initWithFormat:@"First Name: %@",@"jhon"];

            //log-1

            NSLog(@"1 address of oriStr:%p", oriStr);

            weakStr = oriStr;

            //log-2

            NSLog(@"2 address of weakStr:%p", weakStr);

            //strongStr = oriStr;

        }

        //log-3

        NSLog(@"3 address of weakStr:%p", weakStr);

    }

    //log-4

    NSLog(@"4 address of weakStr:%p", weakStr);

    // Do any additional setup after loading the view, typically from a nib.

}



执行结果:
2016-12-14 15:21:57.895 arctest[34075:4533362] 1 address of oriStr:0x60800005f6e0
2016-12-14 15:21:57.899 arctest[34075:4533362] 2 address of weakStr:0x60800005f6e0
2016-12-14 15:21:57.900 arctest[34075:4533362] 3 address of weakStr:0x0
2016-12-14 15:21:57.900 arctest[34075:4533362] 4 address of weakStr:0x0


根据变量的作用域可以知道oriStr的有效范围是"作用域3", 当你在"作用域3"之外访问oriStr这个变量时,编译器会报错.
1.现在有weakStr引用了oriStr, 由于weakStr是__weak类型, 同时oriStr的有效范围是"作用域3"因此第一个log-2打印出了weakStr的地址,这个地址和log-1打印出的oriStr的地址相同(1 address of weakStr:0x60000005e240), 这说明weakStr只是一个oriStr的引用,而不是一个新的对象.
2.在"作用域3"之外的log-3打印出的weakStr的地址是0(2016-12-14 15:21:57.900 arctest[34075:4533362] 3 address of weakStr:0x0),说明在"作用域3"结束之前由于没有对oriStr有任何strong类型的引用,ARC认为oriStr的生命周期就是在"作用域3"之内,同时在"作用域3"结束的时候会对oriStr的ARC的count做减1的操作, 这个时候count为0了,ARC就释放了oriStr的资源.(说明了__weak类型的引用不会增加ARC的count).
3.当我们把//strongStr = oriStr;这行代码的注释去掉之后,可以看一下weakStr的打印情况,输出结果如下:
2016-12-14 15:29:07.634 arctest[34463:4536327] 1 address of oriStr:0x60000004c1e0
2016-12-14 15:29:07.635 arctest[34463:4536327] 2 address of weakStr:0x60000004c1e0
2016-12-14 15:29:07.635 arctest[34463:4536327] 3 address of weakStr:0x60000004c1e0
2016-12-14 15:29:07.636 arctest[34463:4536327] 4 address of weakStr:0x0

可以看到log-3中打印出的weakStr的地址不是0了, 这是为什么呢, 这个主要是由于在"作用域3"结束之前有了一个对oriStr的strong类型的引用, strong类型的引用会导致count加1,那么现在count值是2了,在"作用域3"结束的时候,对count减1处理,这个时候ARC发现减1后,count不是0,因此保留了资源,也就是把oriStr的内容的有效范围扩大到了"作用域2"(注意这里说的是oriStr的内容的作用域,而不是指oriStr变量的作用域,即使对oriStr有了strong类型的引用,在"作用域3"之外使用oriStr变量一样是编译上的错误),因此log-3打印出了weakStr的地址.

4.为啥log-4没有打印出weakStr的地址,请综合上面的描述仔细想一想.

5.注意,下面的代码是没有实际意义的

NSString * __weak weakStr = [[NSString alloc] initWithFormat:@"First Name: %@", @"jhon"];

主要是因为[[NSString allocinitWithFormat:@"First Name: %@"@"jhon"]没有变量保存,也就是说没有作用域(有效范围)!因此后面再有代码操作weakStr的时候,得到的都是一个空的引用.



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值