block本质是什么,需要注意什么?
Block 的本质是一个封装了函数和函数调用环境(捕获的变量)的 Objective-C 对象。Block 的实现基于 C 语言的函数指针,但它们比普通的函数指针更加强大,因为它们能够捕获周围的状态。
在 Objective-C 中,每个 block 实际上是一个结构体,该结构体包含了几个重要的元素:
- isa 指针,表明这是一个对象,并指向该 block 类型的类对象。
- 函数指针,指向 block 的执行体(即 block 里写的代码)。
- 捕获的变量的副本,block 能够捕获其作用域内的变量,这些变量在 block 被定义时拷贝到了 block 结构体中。
- 引用计数,用于在非 ARC 环境下管理 block 的生命周期。
- 其他用于管理 block 生命周期和状态的字段。
使用 block 时需要注意以下几个方面:
-
循环引用:Block 内部如果捕获了 self 或其成员变量,且 self 同时持有这个 block,会产生循环引用,导致内存泄漏。为了打破循环引用,通常会使用 __weak 关键字来声明一个 self 的弱引用。
-
内存管理:在非 ARC 环境下,需要手动管理 block 的拷贝和释放。在 ARC 环境下,block 通常会自动从栈复制到堆上,但仍需要注意循环引用问题。
-
变量捕获:Block 只能捕获其作用域内的变量的值,如果需要在 block 内部修改外部变量,那么这个变量必须使用 __block 修饰符声明。
-
执行环境:Block 在定义时捕获变量的状态,而不是在执行时,所以 block 内部看到的外部变量是在 block 创建时的快照。
-
性能考虑:频繁地创建和销毁大量的 block 可能会对性能造成影响,特别是当这些 block 被拷贝到堆上时。同时,block 捕获大量数据时也会增加内存使用。
-
线程安全:如果 block 在多线程环境中执行,需要确保 block 内部访问的数据是线程安全的。
延伸: block性能考虑和线程安全
理解并注意以上方面,可以有效地使用 block 编程,同时避免常见的陷阱和错误。
1.局部block:
局部Block-CSDN博客
2.gcd:
GCD与Block
3.函数参数是block,调这个block中使用self:
函数参数是block-CSDN博客
4.什么时候strong;
在 Objective-C 中,当你在 block 内部使用 weakSelf 并希望在 block 执行的过程中确保被捕获的对象不会被释放,你会将 weakSelf 转换为 strongSelf。
这个模式是一种预防性的做法,用以确保在 block 执行的时候,即使是在异步操作中,对象(通常是 self)仍然存在。如果不这么做,在异步操作中,self 可能会在 block 执行之前被释放,尤其是当 block 执行不是立即发生时。一旦 self 被释放,尝试访问 weakSelf 将返回 nil,并且在 block 内部调用 self 的方法或者访问其属性将不会执行任何操作。
这是将 weakSelf 转换为 strongSelf 的模式:
__weak typeof(self) weakSelf = self; self.myBlock = ^{ // 将弱引用的 weakSelf 转换为强引用的 strongSelf __strong typeof(weakSelf) strongSelf = weakSelf; // 确保 strongSelf 在 block 执行时还存在 if (strongSelf) { [strongSelf doSomething]; // 其他使用 strongSelf 的代码... } // 如果 strongSelf 为 nil,则意味着原始的 self 已经被释放 };
在这个模式中,一旦 block 开始执行并且 strongSelf 被成功创建,self 的生命周期就会在 block 执行的过程中得到保证。如果 strongSelf 为 nil,则表示原始的 self 已经被释放,block 内部的代码应该处理这种情况,避免执行任何依赖于 self 存在的操作。
总结来说,将 weakSelf 转换为 strongSelf 是为了:
- 确保在 block 的执行期间,self 不会被释放。
- 允许 block 在 self 不存在时正确地处理这种情况,通常是直接返回或者执行一些不依赖于 self 的操作。
这种做法是一种推荐的编程模式,可以避免循环引用的同时也确保了代码的稳定性和安全性。
5. 什么时候拷贝到堆上;
block什么时候拷贝到堆上-CSDN博客
6.weak的本质;
待总结;
7.是否是OC对象?
Block是OC对象吗-CSDN博客
8.Block为什么不能为nil?
OC中Block为什么不能为nil-CSDN博客
9. block可能存在内存的哪里,并举例说明?
Block可能存在内存的哪里
还没有评论,来说两句吧...