返回
iOS基础之block
IOS
2023-12-14 13:28:57
一、Block 的本质
block 的本质是一个OC对象。看下面一段代码:
void (^block)(void) = ^ {
NSLog(@"Hello, world!");
};
定义一个 block ,在 block 中执行一句代码,之后调用 block 。
block();
我们通过 clang 编译器来查看一下编译后的汇编代码:
_block_literal_0:
.align 2
.quad L_OBJC_LABEL_PROTOCOL_$_NSGlobalBlock_
.quad L_OBJC_LABEL_INSTANCE_VARIABLES_$block_literal_0
.quad _block_invoke_0
L_OBJC_LABEL_INSTANCE_VARIABLES_$block_literal_0:
可以看到,block 在编译后被翻译成一个结构体,其中包含了协议、实例变量和调用函数的指针。
二、Block 的内存管理
在 ARC 下,block 的内存管理与普通对象基本相同。在创建一个 block 时,系统会为其分配内存,并在 block 不再被使用时自动释放内存。
但是,在某些情况下,也可能发生内存泄漏。例如,当我们把 block 作为参数传递给另一个函数时,如果该函数没有正确地释放 block,就有可能导致内存泄漏。
为了防止内存泄漏,我们可以使用自动释放池。自动释放池是一个临时内存区,当自动释放池被销毁时,其中所有的对象都会被释放。我们可以使用 @autoreleasepool 块来创建一个自动释放池。
@autoreleasepool {
// 在这里使用 block
}
三、Block 与 ARC 的关系
ARC 可以自动管理 block 的内存,但它并不能防止所有可能的内存泄漏。例如,当我们把 block 作为参数传递给另一个函数时,如果该函数没有正确地释放 block,就有可能导致内存泄漏。
为了防止内存泄漏,我们可以使用自动释放池。自动释放池是一个临时内存区,当自动释放池被销毁时,其中所有的对象都会被释放。我们可以使用 @autoreleasepool 块来创建一个自动释放池。
四、Block 的使用技巧
在使用 block 时,需要注意以下几点:
- 避免在 block 中捕获自变量。如果在 block 中捕获了自变量,那么当自变量被释放后,block 也会被释放。
- 不要在 block 中使用 __block 修饰符。__block 修饰符允许在 block 中修改自变量,但这可能会导致内存泄漏。
- 使用自动释放池来防止内存泄漏。自动释放池是一个临时内存区,当自动释放池被销毁时,其中所有的对象都会被释放。我们可以使用 @autoreleasepool 块来创建一个自动释放池。
五、结语
block 是 iOS 开发中非常重要的一个特性。掌握 block 的使用技巧,可以帮助我们写出更加健壮、高效的代码。