iOS block有几种?存在哪个位置?

在 iOS 开发中,Block 是 Objective-C 和 Swift 中的闭包实现。Block 是一种封装了代码和上下文的对象,可以捕获外部变量并在需要时执行。以下是关于 Block 的类型和存储位置的详细说明:


1. Block 的类型

在 Objective-C 中,Block 可以分为以下几种类型:

1.1 NSGlobalBlock(全局 Block)

  • 特点
    • Block 没有捕获任何外部变量。
    • 类似于全局函数,存储在全局数据区。
  • 示例
    void (^globalBlock)(void) = ^{
        NSLog(@"This is a global block.");
    };
    NSLog(@"%@", globalBlock); // 输出: <__NSGlobalBlock__: 0x...>
    

1.2 NSStackBlock(栈 Block)

  • 特点
    • Block 捕获了外部变量,但未逃逸出当前作用域。
    • 存储在栈上,生命周期与当前作用域绑定。
  • 示例
    int value = 10;
    void (^stackBlock)(void) = ^{
        NSLog(@"Captured value: %d", value);
    };
    NSLog(@"%@", stackBlock); // 输出: <__NSStackBlock__: 0x...>
    

1.3 NSMallocBlock(堆 Block)

  • 特点
    • Block 捕获了外部变量,并且逃逸出当前作用域(例如被复制到堆上)。
    • 存储在堆上,由 ARC 管理内存。
  • 示例
    int value = 10;
    void (^heapBlock)(void) = [^{
        NSLog(@"Captured value: %d", value);
    } copy];
    NSLog(@"%@", heapBlock); // 输出: <__NSMallocBlock__: 0x...>
    

2. Block 的存储位置

Block 的存储位置取决于其类型和捕获的变量:

2.1 全局数据区

  • NSGlobalBlock 存储在全局数据区。
  • 这种 Block 不捕获任何外部变量,类似于全局函数。

2.2 栈

  • NSStackBlock 存储在栈上。
  • 这种 Block 捕获了外部变量,但未逃逸出当前作用域。

2.3 堆

  • NSMallocBlock 存储在堆上。
  • 这种 Block 捕获了外部变量,并且逃逸出当前作用域(例如被复制到堆上)。

3. Block 的内存管理

  • NSGlobalBlockNSStackBlock 不需要手动管理内存。
  • NSMallocBlock 由 ARC 自动管理内存,开发者无需手动释放。

4. Block 的逃逸与非逃逸

  • 非逃逸 Block:Block 在函数返回前执行完毕,通常分配在栈上。
  • 逃逸 Block:Block 被存储或传递到函数外部,通常分配在堆上。

5. Swift 中的闭包

在 Swift 中,闭包的行为与 Objective-C 的 Block 类似:

  • 非逃逸闭包:默认情况下,函数参数中的闭包是非逃逸的。
  • 逃逸闭包:使用 @escaping 标记的闭包是逃逸的,通常分配在堆上。

总结

  • Block 类型:NSGlobalBlock、NSStackBlock、NSMallocBlock。
  • 存储位置:全局数据区、栈、堆。
  • 内存管理:NSMallocBlock 由 ARC 管理,其他类型无需手动管理。
  • Swift 闭包:行为与 Block 类似,逃逸闭包分配在堆上。

如果你有更多问题,欢迎继续提问!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容