返回
揭秘block对Objective-C内存管理的影响
IOS
2023-09-04 07:25:34
block的基本结构
block 是带有自动变量(局部变量)的匿名函数, 是 C 语言的扩充功能,其本质是一个OC对象。
block 的基本结构如下:
^returnType (^blockName)(参数列表) {
// block 体
}
其中,returnType
是 block 的返回值类型,blockName
是 block 的名称,参数列表
是 block 的参数列表,block 体
是 block 的代码块。
block的内存管理
block 在 Objective-C 中的内存管理与普通对象类似,也是通过引用计数来管理的。当一个 block 被创建时,它的引用计数为 1。当一个 block 被一个对象引用时,它的引用计数会增加 1。当一个 block 被一个对象释放时,它的引用计数会减少 1。当一个 block 的引用计数为 0 时,它就会被释放。
block对持有变量的引用计数的影响
block 可以持有外部变量,包括局部变量、成员变量和属性。当一个 block 持有外部变量时,它会对外部变量的引用计数产生影响。
- 当一个 block 持有一个局部变量时,它会使局部变量的引用计数增加 1。
- 当一个 block 持有一个成员变量时,它会使成员变量的引用计数增加 1。
- 当一个 block 持有一个属性时,它会使属性的引用计数增加 1。
当一个 block 释放时,它会释放它所持有的所有外部变量。因此,当一个 block 持有外部变量时,需要小心管理 block 的生命周期,以避免外部变量被意外释放。
block的修饰符
block 可以使用修饰符来修饰它所持有的变量。修饰符可以改变 block 对变量的引用计数的影响。
__block
修饰符:__block
修饰符可以使 block 持有一个局部变量,并使局部变量的引用计数增加 1。__weak
修饰符:__weak
修饰符可以使 block 持有一个弱引用,当弱引用指向的对象被释放时,弱引用会自动变为 nil。__strong
修饰符:__strong
修饰符可以使 block 持有一个强引用,当强引用指向的对象被释放时,强引用不会自动变为 nil。
block的常见问题
在使用 block 时,可能会遇到一些常见的问题。
- block 循环引用:block 循环引用是指一个 block 持有一个对自己的引用,从而导致引用计数永远不会为 0,最终导致内存泄漏。
- block 内存泄漏:block 内存泄漏是指一个 block 持有一个对外部变量的强引用,导致外部变量无法被释放,最终导致内存泄漏。
- block 线程安全:block 线程安全是指一个 block 可以被多个线程同时访问,而不会导致数据损坏。
总结
block 是 Objective-C 中一种强大的工具,可以用来实现各种各样的功能。但是,在使用 block 时需要小心管理 block 的生命周期和引用计数,以避免出现问题。