block、__weak和__strong

block的类型

没有引用引用外部变量的block是全局block(NSGlobalBlock)
引用了外部变量的block在声明时(执行代码是在栈内存),处于栈内存,所以是栈block(NSStackBlock);由于栈中对象的内存由系统管理,对象内存的回收由系统决定,所以为了防止下次调用block时block已被回收,就需要把刚声明的block(栈block)以及block中引用的对象copy到堆上,这时刚才声明的block就变成了堆block(NSMallocBlock)。

	//*****************  block类型 ****************
	//__NSGlobalBlock__
	NSLog(@"%@", ^{
    });
	//__NSStackBlock__
	NSLog(@"%@", ^{
        NSLog(@"%@", obj);
    });
    self.block = ^{
        NSLog(@"%@", obj);
    };
    //__NSMallocBlock__
    NSLog(@"%@", self.block);

block与引用计数

	NSObject *obj = [NSObject new];
	
    __weak NSObject *objw = obj;
    
    NSLog(@"obj:  %ld", CFGetRetainCount((__bridge CFTypeRef)(obj)));//1
    
    NSLog(@"objw:  %ld", CFGetRetainCount((__bridge CFTypeRef)(objw)));//2 __weak修饰的对象不会增加原对象的引用计数,__weak对象的引用计数只是返回原对象retainCount + 1
	
	//引用__weak修饰的对象
	^{
        NSLog(@"objw:  %ld", CFGetRetainCount((__bridge CFTypeRef)(objw)));//2 未增加
    }();
    
	//引用__weak修饰的对象    
	^{
        NSLog(@"objw:  %ld", CFGetRetainCount((__bridge CFTypeRef)(objw)));//2 未增加
    }();

	//引用 非 __weak修饰的对象
	^{
        NSLog(@"obj:  %ld", CFGetRetainCount((__bridge CFTypeRef)(obj)));//2 增加1
    }();
    
	//引用 非 __weak修饰的对象
	^{
        NSLog(@"obj:  %ld", CFGetRetainCount((__bridge CFTypeRef)(obj)));//3 增加1
    }();

	//用__strong修饰的对象	
	^{
		NSLog(@"obj:  %ld", CFGetRetainCount((__bridge CFTypeRef)(obj)));//4
        __strong Obj *objs = objw;
        NSLog(@"obj:  %ld", CFGetRetainCount((__bridge CFTypeRef)(objw)));//6
        NSLog(@"obj:  %ld", CFGetRetainCount((__bridge CFTypeRef)(objs)));//5
        NSLog(@"obj:  %ld", CFGetRetainCount((__bridge CFTypeRef)(obj)));//5
    }();

结论:block内部不会对自己所引用的__weak的变量(objw)增加引用计数,__strong修饰的(__objs)外部的__weak变量(__objw)会增加原变量(__obj)的引用计数,但是block执行完之后__strong修饰的变量引用计数为减1。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值