在 ARC(Automatic Reference Counting)环境下,Block 属性建议使用 修饰,但使用 也是完全可以的。 要理解其中的原因,我们需要从 Block 的内存位置变化以及 ARC 的工作原理两个方面来解释。 核心原因:从“栈”移动到“堆” Block 在内存中主要有三种形态: 1. (全局块):不捕获任何外部变量,存在于数据区(.data),类似全局变量,生命周期伴随整个 App。 2. (栈块):捕获了外部变量,默认创建在栈上。 3. (堆块):当栈块被 后,会复制到堆上。 1. MRC 时代的遗留习惯 (The Origin) 在 MRC(手动管理内存)时代,Block 创建时默认是在栈上的。 如果一个 Block 在栈上,当定义它的函数或方法返回时,栈帧被销毁,Block 的内存也会被回收。 如果此时你只是用 (相当于 ARC 的 )指向它,你持有的只是一个指向已销毁栈内存的野指针。当你稍后调用这个 Block 时,程序就会崩溃。 解决方案:必须对 Block 发送 消息,将其从栈复制到堆上,这样它才能拥有独立的生命周期,在作用域外存活。 因此,在...