不废话,上代码 》》》
1、先说下实现的过程:A到B,B带值到A,A打印或者显示。
2、实现的思路:A调用B声明的Block属性,并且打印或者显示
B声明一个Block,并用这个Block去声明一个Block属性;声明完毕之后,在回访A之前调用这个实现方法或者是 传值操作。
3、具体代码:(这里我用的是模态的方式去进行跳转A、B的,并且我只是做一个简单的测试来使用,所以我将跳转方法放在了Touch方法中来实现 ---》 touchBegan:)
1⃣️、在B(B.h)声明一个Block
Typedef void (^MyBlock) (NSString *)
2⃣️、在B (B.h) 用Block去声明一个属性,用copy修饰
@property (nonatomic, copy) MyBlock Block;
3⃣️、在B中实现B的Block方法
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{
self.Block(@"这个是B传递的字符串信息");
4⃣️、在A中跳转到B,打印传递信息
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{
B * b = [B allocWithZone: NULL];
b.Block = ^ (NSString * info){
NSLog(@"%@",info);
}
[self presentViewController:b animated : NO completion:nil];
这样就能传递成功页面之间的值了,注意一下就是关乎于循环引用的问题,在Block 中使用self会出现问题,因为self调用属性会retain,使得引用计数+1,所以标准做法就是在块体外进行弱引用(__weak和__block),就会将block从栈区转移到堆区,这样就能很好的释放掉Block。
那么如何证明“block内部”打印的是堆地址?
把三个16进制的内存地址转成10进制就是:
定义后前:6171559672
block内部:5732708296
定义后后:5732708296
中间相差438851376个字节,也就是 418.5M 的空间,因为堆地址要小于栈地址,又因为iOS中一个进程的栈区内存只有1M,Mac也只有8M,显然a已经是在堆区了。
另外说下__weak和__block的区别,现在很多都是使用__weak的,因为__block会导致对象release不掉,导致内存泄漏。而__weak因为是弱引用,所以出了块体之外就被释放了,所以使用__weak更安全一点,但是要注意一点的地方就是__weak在某些时候是有短板的,比如我现在想在block里面延迟调用某些东西,因为我是延时调用,此时已经出了块体,所以可能我调用的时候对象已经被删除了,导致崩溃。所以在此时,办法就是强行引用对象。做法很简单,就是在外部__weak 的对象到块体内部的时候__strong强引用一下就好了。
行吧,先讲到这里,等下次想到了再补充好了。以上~
网友评论