是的,代码的确还有问题,第一个问题就是循环引用的问题,在 A 视图的block 代码块中:
bVC.callBackBlock = ^(NSString *text){
NSLog(@"text is %@",text);
self.label.text = text;
};
代码 self.label.text = text; ,在 Block 中引用 self ,也就是 A ,而 A 创建并引用了 B ,而 B 引用 callBackBlock,此时就形成了一个循环引用,而编译器也不会报任何错误,我们需要非常小心这个问题(面试百分百问到我会乱说?)。此时我们通常的解决方法是使用弱引用来解除这个循环:
__weak AViewController *weakSelf = self;
bVC.callBackBlock = ^(NSString *text){
NSLog(@"text is %@",text);
// self.label.text = text;
weakSelf.label.text = text;
};
第二个问题是我自己对 Block 的理解不到位,我们都知道 Block 能截取自动变量,并且是不能在 Block 块中进行修改的(除非用__block修饰符),但是很明显 weakSelf.label.text的值被修改了,并且没有用__block修饰符, 这是为什么呢?因为 label 是个全局变量,而如果像如下的局部变量 a 是不能修改的,编译器也会报错:

局部变量
通过这个小例子发现的两个问题,也算是值得了。
Block 为什么能实现神奇的回调
在这里我不会说什么实现原理,仅仅是个人对 Block 能实现神奇回调的理解,有错误的地方请大家指出。
在先前使用 Block 的过程中,虽然会使用,但是总是有一个疑惑,简单说来就是:
为什么在 A 中的 block 块能调用到 B 中的数据?
回顾一下我们在 B 中所实现的代码,不外乎定义了一个 Block 变量,并在适当的时候传入参数,那么为什么在调用了 self.callBackBlock(_textField.text) 之后,值就神奇传到了 A 中的 Block 块了呢?
通过整理使用的过程,我发现是我们的思维陷入了误区(可能是我个人),我们认为在 B 中传入 _textField.text 参数之后, A 中的 Block 块就可以获取到值。虽然思路是对的,但其实是不完整,导致我们形成了回调的数据是通过某种底层实现传递过去的错觉,这就使得我们认为这不需要深究。
事实是,通过简单的整理我们可以发现完整的回调流程应该是这样的:

回调流程
block 代码块赋值给










