返回
剖析 iOS 面试题中的重点难点——Block
IOS
2023-11-12 17:04:39
Block 的内部实现
Block 是 Objective-C 中的闭包,它允许您将代码块作为参数传递给其他函数。Block 的内部实现基于结构体,它包含指向函数的指针、函数的参数和局部变量。当 Block 被调用时,它会创建一个新的栈帧,并将局部变量压入栈中。然后,它会调用指向函数的指针,并传递参数。函数执行完成后,栈帧被弹出,Block 被销毁。
Block 的结构
Block 的结构如下:
struct Block {
void *isa;
int flags;
int reserved;
void (*invoke)(void *, ...);
struct BlockDescriptor *descriptor;
};
isa
:指向 Block 的类对象的指针。flags
:包含 Block 的标志位,例如是否可以捕获外部变量。reserved
:保留字段,未被使用。invoke
:指向 Block 函数的指针。descriptor
:指向 Block 符的指针。
Block 是否属于类
Block 不是类,它是一种数据结构。Block 虽然具有函数的某些特性,但它不是类实例,也不支持面向对象编程的特性,例如继承和多态性。
Block 的类型
Block 有两种类型:
- 堆 Block :在堆上分配内存的 Block。堆 Block 可以捕获外部变量,并且可以在 Block 之间传递。
- 栈 Block :在栈上分配内存的 Block。栈 Block 不能捕获外部变量,只能在函数内部使用。
一个 int 变量被 __block 修饰与否的区别
当一个 int 变量被 __block 修饰时,它表示该变量可以被 Block 捕获。这意味着 Block 可以修改该变量的值,即使 Block 在函数之外被调用。如果一个 int 变量没有被 __block 修饰,则它不能被 Block 捕获,Block 只能访问该变量的副本。
以下示例演示了 __block 修饰符的使用:
void testBlock() {
int value = 10;
// 创建一个 Block 并捕获变量 value
void (^block)(void) = ^{
value++;
};
// 调用 Block
block();
// 打印 value 的值
printf("Value: %d\n", value);
}
在上面的示例中,变量 value 被 __block 修饰,因此它可以被 Block 捕获。当 Block 被调用时,它会修改变量 value 的值。因此,当打印 value 的值时,输出结果为 11。
如果您想了解更多关于 Block 的信息,可以参考 Apple 的官方文档:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html。