從 C 的聲明符到 Objective-C 的 block 語法

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的函數。

block 修飾符

Apple 在上述三個修飾符的基礎上增長了一個修飾符,block 修飾符^.

block 修飾符和指向函數的指針很是類似。上面咱們提到int (*f)()是一個指向返回int函數的指針,相似地,int (^b)() 是一個指向返回int函數的 block 指針,簡稱返回int的 block。

由於 block 老是指向函數的,因此int ^aint ^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。

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

相關文章
相關標籤/搜索