Objective-C 的 block 语法看起来比较复杂,其实它只是一个简单的扩展。下面咱们从 C 的声明符开始,一步一步地引入 block 概念。objective-c
首先复习一下 C 的声明符:segmentfault
int a
int
指定了类型,a
是变量的名称。数组
声明符可使用修饰符,C 有三种修饰符:*
、[]
、()
。闭包
int *a
a
是指向int
的一个指针。函数
int a[]
a
是一个由int
组成的数组。spa
int f()
f
是一个返回int
的函数。指针
这些修饰符能够混合使用。混合时,从变量名称开始往右读,读到尽头或闭括号以后再从变量名称开始往左读。code
例如:blog
int *a[]
先往右读,[]
是有一个数组,再往左读int *
是指向int
的指针。因此int *a[]
就是由指向int
的指针组成的数组,等价于int *(a[])
。ci
再如:
int (*a)[]
先由a
往右读,碰到)
,所以再往左读,读到*
,所以是一个指针。而后再往右读[]
,再往左读int
。因此最后int (*a)[]
是指向由int
组成的数组的指针。
同理,int *f()
,是一个函数,返回一个指向int
的指针。而int (*f)()
则是一个指针,指向一个返回int
的函数。
Apple 在上述三个修饰符的基础上增长了一个修饰符,block 修饰符^
.
block 修饰符和指向函数的指针很是类似。上面咱们提到int (*f)()
是一个指向返回int
函数的指针,相似地,int (^b)()
是一个指向返回int
函数的 block 指针,简称返回int
的 block。
由于 block 老是指向函数的,因此int ^a
和int ^b()
都是非法的,由于不存在指向int
的 block。
block 和指向函数的指针的区别在于,block 建立了一个闭包。
将声明符中的变量名称去除后,咱们就获得了抽象声明符。在 C 中,抽象声明符用于如下三种情形:
int *a; long *b = (long *) a;
。sizeof()
的参数。malloc(sizeof(long *));
int f(long *);
Objective-C 扩展了抽象声明符的用法:用于声明方法的参数和返回值。
- (long **)methodWithArgument:(int *)a;
一样适用于 block 声明符:
- (void)methodWithArgument:(int(^)())block; - (void)anotherMethodWithArgument:(void(^)(long arg1))block;
^
除了做为修饰符使用以外,还能够做为操做符使用,将函数转化为 block。
block = ^(long a, long b) { int c = a + b; return c; }
注意咱们这里省略了 block 的返回值的类型声明,由于 Objective-C 会从return
语句中推导出类型。
Objective-C 的 block 语法是在 C 的标准语法基础上的扩展。Objective-C 中的 block 不过是一个建立了闭包的指向函数的指针。
原文 From C Declarators to Objective-C Blocks Syntax
编译 SegmentFault