Objective-C 14 代碼塊Block

來源:互聯網
上載者:User

標籤:

Blocks Block 程式碼片段

Block封裝了一段代碼,可以在任何時候執行。它是對C語言中函數的擴充,它實際上是C語言實現的,所以它在各種以C作為基礎的語言哪都是有效,包括Objective-C、C++以及Objective-C++。

Block可以作為函數參數或者函數的返回值,而其本身又可以帶輸入參數或返回值。它和傳統的函數指標很類似,但是有區別:

block是內嵌函式的,並且預設情況下它對局部變數是唯讀。

蘋果官方建議盡量多用block。在多線程、非同步任務、集合遍曆、集合排序、動畫轉場用的很多。

1 定義代碼塊

<returntype>(^blockname)(list of arguments) = ^(arguments){body;};

編譯器可以通過代碼塊的內容推匯出傳回型別,所以可以省略它。如果代碼塊中沒有參數,也可以省略。

int (^Sum)(int, int) = ^(int a, int b){
    return a+b;
}

=號前面是代碼塊的定義,而等號後面是實現內容。

定義了一個名叫Sum的block對象,帶有兩個int型參數,返回int。=式右邊是block的具體實現。

2 使用代碼塊將代碼塊聲明成了變數,所以可以像函數一樣使用它Sum(2,22);這行代碼中沒有冪符號,這是因為只有在定義和實現代碼塊的時候才需要使用它,調用時則不需要。
int (^Sum)(int, int) = ^(int a, int b){    NSLog(@"block Sum 被調用了");          return a+b;};NSLog(@"調用Sum之前。");int a = Sum(2,22);NSLog(@"a=%i",a);
輸出結果:

2016-02-25 19:14:46.709 命令列工程[924:132247] 調用Sum之前。2016-02-25 19:14:46.710 命令列工程[924:132247] block Sum 被調用了2016-02-25 19:14:46.710 命令列工程[924:132247] a=24

這樣會固定block,只能使用Sum調用,我們可以通常使用typedef。

3 使用typedef關鍵字

typedef int (^MySum) (int, int);

//聲明了一個block變數,類型為MySum。使用typedef可以聲明無限多個block變數,方便使用。

#import <Foundation/Foundation.h>typedef int (^MySum)(int, int);int main(int argc, const char * argv[]) {    @autoreleasepool {        MySum sum1 = ^(int a, int b) {            return a + b ;        };        MySum sum2 = ^(int a, int b) {            return a*b;        };        NSLog(@"調用sum1 =%i",sum1(10,10));        NSLog(@"調用sum2 =%i",sum2(10,10));    }    return 0;}
輸出:
2016-02-25 19:21:22.574 命令列工程[1002:135364] 調用sum1 =202016-02-25 19:21:22.575 命令列工程[1002:135364] 調用sum2 =100Program ended with exit code: 0
4 直接使用代碼塊 

使用block通常不需要建立一個代碼塊變數,而是在代碼中內聯代碼塊的內容。

NSArray *stringArray = [NSArray arrayWithObjects:@"any", @"hello", @"body",@"good",@"cool",nil];        //升序排列        NSArray *sortedArray = [stringArray sortedArrayUsingComparator:^(id string1, id string2){            //NSLog(@"string1=%@,string2=%@",string1,string2);            return [string1 compare:string2];        }];        NSLog(@"sortArray:%@", sortedArray);
輸出結果:
2016-08-15 14:34:06.257 命令列工程[1478:103112] sortArray:(    any,    body,    cool,    good,    hello)

5 局部變數

Blocks可以訪問局部變數,但不可以修改。(預設情況下)

#import <Foundation/Foundation.h>typedef int (^MySum)(int, int);int main(int argc, const char * argv[]) {    @autoreleasepool {        int local  = 100;        __block int va = 110;        MySum sum = ^(int a, int b) {            NSLog(@"local = %i,va = %i",local, va);            //local++;  Variable is not assignable(misssing __block typedef  specifier)            va++;            return a + b +va;        };        NSLog(@"調用Sum之前。");        int a = sum(10,10);        NSLog(@"調用Sum之後。");        NSLog(@"va = %i",va);        NSLog(@"a=%i",a);    }    return 0;}
輸出:
2016-02-25 19:23:34.909 命令列工程[1028:136661] 調用Sum之前。2016-02-25 19:23:34.910 命令列工程[1028:136661] local = 100,va = 1102016-02-25 19:23:34.910 命令列工程[1028:136661] 調用Sum之後。2016-02-25 19:23:34.910 命令列工程[1028:136661] va = 1112016-02-25 19:23:34.910 命令列工程[1028:136661] a=131Program ended with exit code: 0
由上述例子可以看出局部變數local是不可以在block中改變的,如果修改會警告??:

Variable is not assignable(misssing __block typedef  specifier)

而局部變數va是可以修改的,加上__block(兩個底線)。

有些變數無法聲明為__block類型的:

沒有長度可變的數組;

沒有包含可變數組的結構體。

局部變數值

double a1 = 10,b = 20;        SampleBlock sample = ^{            return a1*b;        };        NSLog(@"%f",sample());        a1 = 20;        b = 50;        NSLog(@"%f",sample());
結果:
2016-08-15 14:43:44.172 命令列工程[1573:107965] 200.0000002016-08-15 14:43:44.175 命令列工程[1573:107965] 200.000000
我剛開始以為第二個會輸出1000,但是不是。
這是因為變數是局部變數,代碼塊會在定義時複製並儲存它們的狀態,所以兩次輸出結果一樣。

6 全域變數

將上面的變數改為全域變數會是怎樣的結果呢?

static double a1 = 10,b = 20;        SampleBlock sample = ^{            return a1*b;        };        NSLog(@"%f",sample());        a1 = 20;        b = 50;        NSLog(@"%f",sample());
結果:

2016-08-15 15:00:22.142 命令列工程[1633:113895] 200.0000002016-08-15 15:00:22.142 命令列工程[1633:113895] 1000.000000
這說明block定義時不會複製全域變數的值。並且block可以更改全域變數的值。


Objective-C 14 代碼塊Block

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.