为什么Objective-C块不像其他Objective-C对象那样通过指针处理?

cfi*_*her 2 cocoa objective-c objective-c-blocks

在使用块的代码中,您经常会看到如下声明:

typedef void(^Thunk)(void);
Thunk block1 = ^{NSLog(@"%d %p",i, &i);};
Run Code Online (Sandbox Code Playgroud)

代替

typedef void(^Thunk)(void);
Thunk *block1 = ^{NSLog(@"%d %p",i, &i);};
Run Code Online (Sandbox Code Playgroud)

块似乎是唯一直接处理的Objective-C对象,而不是通过指针.为什么是这样?它们不是常规物体吗?

Nik*_*uhe 7

如果您想知道丢失的内容*:在您的示例中,您键入了隐藏语法的块.您也可以使用其他对象执行此操作:

typedef NSNumber *Number;
Number foo = @42;
Run Code Online (Sandbox Code Playgroud)

将块分配给实际分配指针的变量时.

块有点像C数组:块文字是由编译器创建的结构.块变量是幕后的指针.


rob*_*off 5

你没有"直接"处理一个块.你间接处理它.

语法void (^)(void)声明指向块的指针."block"类型没有语法; 类型"指向块的指针"只有语法.

语言规范:

抽象的声明者,

int (^)(char, float)
Run Code Online (Sandbox Code Playgroud)

描述了一个Block的引用,当被调用时,它接受两个参数,第一个是char类型,第二个是float类型,并返回一个int类型的值.引用的块是不透明数据,可能驻留在自动(堆栈)内存,全局内存或堆内存中.

相关位是"描述对块的引用 ".

规范并不完全一致,因为(例如)它指的是"具有块类型的变量"和"块变量声明".但实际上变量总是保存一个块的引用(指针),并且永远不会直接将一个块作为其值.