block、__weak和__strong

本文详细介绍了Block的三种类型:全局Block、栈Block和堆Block,以及它们之间的转换。同时,文章探讨了Block对引用计数的影响,特别是__weak和__strong修饰符在Block中的行为。通过实例展示了Block如何影响对象的引用计数,并得出结论:Block不会增加__weak变量的引用计数,而__strong修饰的__weak变量会增加原对象的引用计数,但Block执行完后__strong修饰的变量引用计数会减1。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值