Blocks Programming Topics

 

 

    最近的工做中比較頻繁的用到了Block,不在是之前當作函數指針的替代或者某些API只有Blocks形式的接口才不得已用之了,發現本身對其瞭解仍是太淺,特別是變量的生存期,按慣例仍是翻譯官方文檔,原文連接javascript

 

 

介紹

Block 對象是C語言層面的語法,也是一個運行時特性. 它們很相似與標準的C函數,可是除了可執行的代碼,它們還包含了與自動(棧)或託管(堆)的內存所綁定的變量。所以一個block維護了一系列的狀態(即數據),在執行時會改變代碼的行爲。html

你可使用blocks編寫函數表達式當參數傳入API,也能夠將其保存下來用於多線程。Blocks在回調(回調的概念)中很是有用,由於block不只包含着回調時須要執行的代碼,還包含了執行代碼時須要的數據。java

你能夠在Mac OS X 10.6和iOS 4.0以後的版本上的GCC附帶的Clang上使用。blocks運行時庫是開源的,見此 LLVM’s compiler-rt subproject repository.Blocks也已經呈現給了C標準工做組,見 N1370: Apple’s Extensions to C (其中包含了垃圾回收). 正如Objective-C和C++都是C的衍生語言,blocks也被設計成能夠在這三種語言中使用 (如同Objective-C++). (語法也能夠表現出其目標).ios

 

你應該閱讀本文檔來學習block的相關知識,以將block用於C,C++,Objective-C中,並提升你的程序的效率可可維護性。數組

 

文檔結構

本文檔包括如下章節:安全

  • "Blocks入門" 提供了快速,使用的blocks簡介數據結構

  • 「總體概念」 提供了blocks在概念上的介紹多線程

  • "聲明和建立Blocks" 爲您展現如何聲明block變量及實現blocks閉包

  • "Blocks和變量" 描述blocks和變量之間的相互做用, __block 修飾符的做用app

  • "使用Blocks" 詳解各類用法範式 

Blocks入門

下面章節使用實際的例子幫助您入門blocks

聲明和使用Block

你要使用^操做符去聲明一個block變量,^也是標示着一段block文字的開始。block的實體包含在{}中,以下所示(形同C,;表示語句的終結):

 

Objective-c代碼    收藏代碼
  1. int multiplier = 7;  
  2. int (^myBlock)(int) = ^(int num) {  
  3.     return num * multiplier;  
  4. };  
 示例的詳解以下(圖片很差翻譯湊合着看): 


 

注意block可使用其定義範圍內的變量.

若是你把block聲明爲一個變量,你能夠把它當一個函數(function,本文中特指C語言形式的函數)同樣調用:

 

Objective-c代碼    收藏代碼
  1. int multiplier = 7;  
  2. int (^myBlock)(int) = ^(int num) {  
  3.     return num * multiplier;  
  4. };  
  5.    
  6. printf("%d", myBlock(3));  
  7. // prints "21"  

 

直接使用Block

在不少場景下,你不須要定義一個block變量,做爲替代,僅僅只須要在須要block參數的地方寫block文字便可。下例使用了qsort_b 函數. qsort_b 很相似標準的 qsort_r 函數,不過它使用block做爲最後一個參數.

 

Objective-c代碼    收藏代碼
  1. char *myCharacters[3] = { "TomJohn""George""Charles Condomine" };  
  2.    
  3. qsort_b(myCharacters, 3, sizeof(char *), ^(const void *l, const void *r) {  
  4.     char *left = *(char **)l;  
  5.     char *right = *(char **)r;  
  6.     return strncmp(left, right, 1);  
  7. });  
  8.    
  9. // myCharacters is now { "Charles Condomine""George""TomJohn" }  

 

Cocos中的Blocks

許多 Cocoa frameworks 中的方法(method,特指Objecitve-C的方法即[])使用block做爲參數, 常見於對集合中對象的操做或一個操做完成以後的回調. 下例展現和如何在NSArray 的方法 sortedArrayUsingComparator: 中使用block。該方法使用一個block做爲參數. 例子中的block被定義爲一個 NSComparator 類型的局部變量:

 

Objective-c代碼    收藏代碼
  1. NSArray *stringsArray = [NSArray arrayWithObjects:  
  2.                                  @"string 1",  
  3.                                  @"String 21",  
  4.                                  @"string 12",  
  5.                                  @"String 11",  
  6.                                  @"String 02", nil];  
  7.    
  8. static NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch | NSNumericSearch |  
  9.         NSWidthInsensitiveSearch | NSForcedOrderingSearch;  
  10. NSLocale *currentLocale = [NSLocale currentLocale];  
  11.    
  12. NSComparator finderSortBlock = ^(id string1, id string2) {  
  13.    
  14.     NSRange string1Range = NSMakeRange(0, [string1 length]);  
  15.     return [string1 compare:string2 options:comparisonOptions range:string1Range locale:currentLocale];  
  16. };  
  17.    
  18. NSArray *finderSortArray = [stringsArray sortedArrayUsingComparator:finderSortBlock];  
  19. NSLog(@"finderSortArray: %@", finderSortArray);  
  20.    
  21. /*  
  22. Output:  
  23. finderSortArray: (  
  24.     "string 1",  
  25.     "String 02",  
  26.     "String 11",  
  27.     "string 12",  
  28.     "String 21"  
  29. )  
  30. */  
 
__block變量

blocks有一個強大的特性,即它能夠修改其當前詞法範圍內的變量. 只要對變量加上 __block 存儲修飾符. 稍微修改上面的例子, 使用一個block變量去統計下例中有多少字符串是相同的。例子中的block仍是直接使用的,並用到了叫 currentLocale 的只讀變量:

 

Objective-c代碼    收藏代碼
  1. NSArray *stringsArray = [NSArray arrayWithObjects:  
  2.                          @"string 1",  
  3.                          @"String 21", // <-  
  4.                          @"string 12",  
  5.                          @"String 11",  
  6.                          @"Strîng 21", // <-  
  7.                          @"Striñg 21", // <-  
  8.                          @"String 02", nil];  
  9.    
  10. NSLocale *currentLocale = [NSLocale currentLocale];  
  11. __block NSUInteger orderedSameCount = 0;  
  12.    
  13. NSArray *diacriticInsensitiveSortArray = [stringsArray sortedArrayUsingComparator:^(id string1, id string2) {  
  14.    
  15.     NSRange string1Range = NSMakeRange(0, [string1 length]);  
  16.     NSComparisonResult comparisonResult = [string1 compare:string2 options:NSDiacriticInsensitiveSearch range:string1Range locale:currentLocale];  
  17.    
  18.     if (comparisonResult == NSOrderedSame) {  
  19.         orderedSameCount++;  
  20.     }  
  21.     return comparisonResult;  
  22. }];  
  23.    
  24. NSLog(@"diacriticInsensitiveSortArray: %@", diacriticInsensitiveSortArray);  
  25. NSLog(@"orderedSameCount: %d", orderedSameCount);  
  26.    
  27. /*  
  28. Output:  
  29.    
  30. diacriticInsensitiveSortArray: (  
  31.     "String 02",  
  32.     "string 1",  
  33.     "String 11",  
  34.     "string 12",  
  35.     "String 21",  
  36.     "Str\U00eeng 21",  
  37.     "Stri\U00f1g 21"  
  38. )  
  39. orderedSameCount: 2  
  40. */  

總體概念

 

Block對象提供了建立特殊函數的方法,函數體可用C,Objective-C,C++等C類的語言作表達式. 在其餘的語言環境中,block變量可能會被叫作"閉包(closure)", 而在這裏,除非和標準C術語的一段(block)代碼混淆的狀況以外,通常稱爲"blocks"。

Block 功能性

一個block就是一塊匿名的代碼塊:

  • 和函數同樣有含類型的參數列表
  • 有直接聲明或可推斷出的返回值
  • 能夠得到當前詞法範圍的狀態
  • 有能力修改當前詞法範圍的狀態
  • 能夠和當前詞法範圍的其餘block共同修改狀態
  • 能夠持續共享和修改當前詞法範圍的狀態,甚至在當前詞法範圍銷燬以後

你能夠copy一個block還能夠將其傳到別的線程以延後執行 (或本線程的執行循環裏). 編譯器和運行時會把block裏用到的全部變量保存到該block的全部拷貝的生存期後。儘管blocks能夠由純C或C++寫成,但block自己始終是一個Objective-C變量.

用法

Blocks通常都是小段的,自成體系的代碼塊. 所以,特別適合用在封轉並行操做所需的數據,或用於集合中,以及操做完成後的回調.

Blocks基於兩大理由,是傳統回調函數的優秀替代品:

  1. 容許你把具體實現代碼寫在調用該方法的地方.

     

    Blocks也常常是framework的方法參數.

        
  2. 能夠訪存局部變量. 不須要像之前的回調同樣,把在操做後全部須要用到的數據封裝成特定的數據結構, 你徹底能夠直接訪問局部變量.

 

 

聲明和建立Blocks

聲明Block引用

 

Block變量保持blocks的引用. 聲明block的語法相似於聲明函數指針,區別之處在於使用^而不是*.block的類型取決於C的類型系統. 下面都是有效的block變量聲明:

Objective-c代碼    收藏代碼
  1. void (^blockReturningVoidWithVoidArgument)(void);  
  2. int (^blockReturningIntWithIntAndCharArguments)(int, char);  
  3. void (^arrayOfTenBlocksReturningVoidWithIntArgument[10])(int);  

 

 

 

 

 

Blokcs也支持可變參數即(...). 若是不帶參數則必須在參數列表中指定 void .

Blocks被設計爲徹底的類型安全,編譯器可由一整套的元數據去判斷blocks,blocks的參數,及返回值的有效性(這句沒太看懂,原文是Blocks are designed to be fully type safe by giving the compiler a full set of metadata to use to validate use of blocks, parameters passed to blocks, and assignment of the return value)。 你能夠把block強制轉換爲任意類型的指針,反之亦然。不過,你不能像對指針同樣用*運算符對block進行解引用(dereference)操做,由於block的大小沒法在編譯時算出.

你也能夠建立blocks的類型,在幾個地方用到一樣函數簽名的block時,這是一種很好的作法:

 

 

Objective-c代碼    收藏代碼
  1. typedef float (^MyBlockType)(float, float);  
  2.    
  3. MyBlockType myFirstBlock = // ... ;  
  4. MyBlockType mySecondBlock = // ... ;  

 

 

建立Block

使用 ^ 操做符標示出block表達式的字面開始部分. 後面跟隨着包含參數列表的().block主體則是包含在{}之中。 下例展現瞭如何定義一個簡單的block,並將其賦值給以前定義的變量 (oneFrom).最後由常規的 ; 也是c語言的語句結束符結束

 

Objective-c代碼    收藏代碼
  1. int (^oneFrom)(int);  
  2.    
  3. oneFrom = ^(int anInt) {  
  4.     return anInt - 1;  
  5. };  

  若是你不想顯式的聲明block的返回值,也能夠由block內容自動推斷出來。若是返回值是可推斷的,而且參數列表爲 void, 你也能夠省略參數列表. 當有多個返回語句時,它們必須是類型一直的(必要時會進行強行轉換).

 

 

全局Blocks

在文件層面上,你可使用block當全局的字面文字:

Objective-c代碼    收藏代碼
  1. #import <stdio.h>  
  2.    
  3. int GlobalInt = 0;  
  4. <p>int (^getGlobalInt)(void) = ^{ return GlobalInt; };</p>  
 
 

 

Blocks和變量

本部分闡述blocks和變量之間的交互做用,包括內存管理.

變量的類型

在block的主體代碼塊中,變量能夠分爲五種.

你能夠引用三種標準類型的變量,就如同函數傳參:

  • 全局變量,包括靜態局部變量

  • 全局函數 (理論上來講不是變量)

  • 做用域(enclosing scope)內的局部變量和參數

Blocks還支持另外兩種類型的變量:

  1. 在函數級別的 __block 變量. 它們在block中是可變的 (同時也在做用域中可變),若是有block被拷貝到了堆(heap)上,則它們也會被保存.

  2. const imports.

最後,在一個方法的具體實現中,blocks能夠引用Objective-C的實體變量,見 「對象和Block變量.」

block使用變量適用以下規則:

  1. 全局變量是可訪存的,包括做用域內的靜態變量.

  2. block的參數是可訪存的 (和函數的參數同樣).

  3. 做用域內的局部棧(非靜態)變量被當作 const 變量.

    它們的值以block表達式在程序的點爲準. 在嵌套blocks中,則是裏該block最近的做用域中的值爲準.

  4. 詞法做用域中的局部變量有 __block 存儲修飾符的,是按引用傳遞並能夠修改.

    全部的變更都反應到做用域中,包括其餘在本做用域內定義的block中作的修改.

    詳見 「__block 存儲類型.」

  5. 在block內部聲明的局部變量,就和函數內聲明的變量同樣.

    每次調用block都產生變量的新的拷貝,這些變量輪流被當作 const 或按引用傳遞的變量用在block內部.

下例使用局部非靜態變量:

 
Objective-c代碼    收藏代碼
  1. int x = 123;  
  2.    
  3. void (^printXAndY)(int) = ^(int y) {  
  4.    
  5.     printf("%d %d\n", x, y);  
  6. };  
  7.    
  8. printXAndY(456); // prints: 123 456  
 

必需要注意,若是想在block內改變x的值,會致使錯誤:

 

Objective-c代碼    收藏代碼
  1. int x = 123;  
  2.    
  3. void (^printXAndY)(int) = ^(int y) {  
  4.    
  5.     x = x + y; // error  
  6.     printf("%d %d\n", x, y);  
  7. };  
 

若是想要在block內改變變量,你要使用 __block 類型的存儲修飾符,詳見「 __block 存儲類型.」

 

The __block Storage Type

你能夠指明一個導入的變量爲可變的便可讀寫的,只須要使用 __block 類型存儲修飾符. __block 存儲類型類不一樣於 registerauto,  但和static 存儲類型同樣,對於局部變量提供了可變的能力.

 

__block 變量生存於存儲區內,並供當前詞法範圍的全部blocks共享使用. 所以,該存儲區將存活到block棧frame銷燬以後,甚至在其餘拷貝或聲明瞭這些block的block銷燬後 (好比壓到隊列中供後續執行). 在給定的詞法範圍裏的多個blocks能夠同時使用一個共享的變量.(這段我整個沒看懂,原文是__block variables live in storage that is shared between the lexical scope of the variable and all blocks and block copies declared or created within the variable’s lexical scope. Thus, the storage will survive the destruction of the stack frame if any copies of the blocks declared within the frame survive beyond the end of the frame (for example, by being enqueued somewhere for later execution). Multiple blocks in a given lexical scope can simultaneously use a shared variable.)

 

做爲優化, block變量和block自己同樣開始是存儲在棧上. 但若是用Block_copy (若是是Objecitve-C環境下, 能夠直接向block發送 copy)對block進行拷貝, 變量就會拷貝到堆上. 所以 __block 變量的地址是能夠改變的.

對於 __block 變量還有兩個更嚴格的限制: 不能是變長數組,也不能是含有C99的變長數組的結構體.

下例示範如何使用 __block 變量:

 

 

Objective-c代碼    收藏代碼
  1. __block int x = 123; //  x lives in block storage  
  2.    
  3. void (^printXAndY)(int) = ^(int y) {  
  4.    
  5.     x = x + y;  
  6.     printf("%d %d\n", x, y);  
  7. };  
  8. printXAndY(456); // prints: 579 456  
  9. // x is now 579  
 
下例展現幾種變量和blocks之間的交互:

 

Objective-c代碼    收藏代碼
  1. extern NSInteger CounterGlobal;  
  2. static NSInteger CounterStatic;  
  3.    
  4. {  
  5.     NSInteger localCounter = 42;  
  6.     __block char localCharacter;  
  7.    
  8.     void (^aBlock)(void) = ^(void) {  
  9.         ++CounterGlobal;  
  10.         ++CounterStatic;  
  11.         CounterGlobal = localCounter; // localCounter fixed at block creation  
  12.         localCharacter = 'a'; // sets localCharacter in enclosing scope  
  13.     };  
  14.    
  15.     ++localCounter; // unseen by the block  
  16.     localCharacter = 'b';  
  17.    
  18.     aBlock(); // execute the block  
  19.     // localCharacter now 'a'  
  20. }  
 
對象和Block變量

Blocks支持Objecitve-C和C++對象,還包括其餘的能夠當作變量的blocks.

Objective-C對象

在引用計數的環境下,默認狀況若是你引用了一個Objective-C對象,它將會被retain,即便你只是使用了這個對象的實體變量. 若是對象使用了 __block 存儲修飾符,則不會被retain.

Note: 在垃圾回收的環境下,若是你對變量同時使用了 __weak 和 __block 修飾符, block將不會保證其生存期.

 

若是你在方法中使用了block,而且使用到了對象的實體變量,那麼內存管理的規則將會更微妙:

  • 若是你使用了改實體變量的引用,則 self 將被retain;

  • 若是你是按指訪問該實體變量,則存儲那個實體變量將被retain.

下例展現這兩種狀況的差異:

 

Objecitve-c代碼    收藏代碼
  1. dispatch_async(queue, ^{  
  2.     // instanceVariable is used by reference, self is retained  
  3.     doSomethingWithObject(instanceVariable);  
  4. });  
  5.    
  6.    
  7. id localVariable = instanceVariable;  
  8. dispatch_async(queue, ^{  
  9.     // localVariable is used by value, localVariable is retained (not self)  
  10.     doSomethingWithObject(localVariable);  
  11. });  
 
C++對象

你能夠在block內使用C++變量. 在成員函數中,對成員變量和函數的引用實際上都是隱式使用了 this 指針,故而都是可變的. 當block被拷貝的時候,有兩種狀況須要留心:

  • 若是你使用的是棧基(stack-based)的C++變量,而且有 __block 存儲修飾符, 一般使用拷貝構造函數來構造對象.

  • 除此之外的棧基C++對象, 則必需要有const拷貝構造函數(形如 Object(const Object&o)),拷貝這些對象時將使用該方法.

Blocks

當拷貝一個block,該block內全部引用到的其餘block都將被拷貝,若是改block使用到的block變量裏引用到了別的block,則別的block也將被拷貝.

當拷貝一個棧基block,你將獲得一個新block. 若是拷貝一個堆基的block,則僅僅是增長其引用計數,在拷貝函數和方法返回後還會降回去.

 

 

使用Blocks

調用Block

把一個block聲明爲一個變量,你就能夠把它當作函數同樣用,以下所示:

 

Objective-c代碼    收藏代碼
  1. int (^oneFrom)(int) = ^(int anInt) {  
  2.     return anInt - 1;  
  3. };  
  4.    
  5. printf("1 from 10 is %d", oneFrom(10));  
  6. // Prints "1 from 10 is 9"  
  7.    
  8. float (^distanceTraveled) (float, float, float) =  
  9.                           ^(float startingSpeed, float acceleration, float time) {  
  10.    
  11.     float distance = (startingSpeed * time) + (0.5 * acceleration * time * time);  
  12.     return distance;  
  13. };  
  14.    
  15. float howFar = distanceTraveled(0.09.81.0);  
  16. // howFar = 4.9  
你也能夠把block當參數傳給函數或者方法.某些場合,你也能夠"內聯(inline)"的建立block.

使用Block做爲函數參數

你能夠傳一個block當參數給函數,就和其餘類型的參數同樣. 不少狀況,你都不必聲明blocks, 而是簡單的在哪裏須要就哪裏直接建立. 下例展現使用qsort_b 函數. qsort_b 相似於標準的 qsort_r 函數,不過只是把最後一個參數改成block.

 

Objective-c代碼    收藏代碼
  1. char *myCharacters[3] = { "TomJohn""George""Charles Condomine" };  
  2.    
  3. qsort_b(myCharacters, 3, sizeof(char *), ^(const void *l, const void *r) {  
  4.     char *left = *(char **)l;  
  5.     char *right = *(char **)r;  
  6.     return strncmp(left, right, 1);  
  7. });  
  8. // Block implementation ends at "}"  
  9.    
  10. // myCharacters is now { "Charles Condomine""George""TomJohn" }  

 

注意block被整個包含在函數的參數列表中.

下例演示如何在 dispatch_apply 函數中使用block. dispatch_apply 聲明以下:

 

Objective-c代碼    收藏代碼
  1. void dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t));  

 

函數將block投遞到調度隊列中供屢次調用. 一共三個參數,其中第一個是調用總次數,第二個是投遞到的隊列,最後是block自己,而這個block帶有一個參數,即當前被調用的次數.

 

能夠僅僅使用 dispatch_apply 去打印打錢的調度下標,以下:

 

Objective-c代碼    收藏代碼
  1. #include <dispatch/dispatch.h>  
  2. size_t count = 10;  
  3. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
  4.    
  5. dispatch_apply(count, queue, ^(size_t i) {  
  6.     printf("%u\n", i);  
  7. });  

 

使用Block做爲方法參數

 

Cocoa 提供了不少使用blocks的方法, 你能夠傳遞block做爲參數,就像調用其餘的方法同樣.

下例展現如何使用給定的過濾條件爲數組排出前五個元素.

 

Objectvie-c代碼    收藏代碼
  1. NSArray *array = [NSArray arrayWithObjects: @"A", @"B", @"C", @"A", @"B", @"Z",@"G", @"are", @"Q", nil];  
  2. NSSet *filterSet = [NSSet setWithObjects: @"A", @"Z", @"Q", nil];  
  3.    
  4. BOOL (^test)(id obj, NSUInteger idx, BOOL *stop);  
  5.    
  6. test = ^ (id obj, NSUInteger idx, BOOL *stop) {  
  7.    
  8.     if (idx < 5) {  
  9.         if ([filterSet containsObject: obj]) {  
  10.             return YES;  
  11.         }  
  12.     }  
  13.     return NO;  
  14. };  
  15.    
  16. NSIndexSet *indexes = [array indexesOfObjectsPassingTest:test];  
  17.    
  18. NSLog(@"indexes: %@", indexes);  
  19.    
  20. /*  
  21. Output:  
  22. indexes: <NSIndexSet: 0x10236f0>[number of indexes: 2 (in 2 ranges), indexes: (0 3)]  
  23. */  

 

下例是判斷一個 NSSet 對象是否包含了一個局部變量,並設置另外一個局部變量(found),在查找到的狀況下 爲 YES (並中止查找) . 注意 found 被聲明爲了 __block 變量, 且block是用內聯方式定義的:

 

Objective-c代碼    收藏代碼
  1. __block BOOL found = NO;  
  2. NSSet *aSet = [NSSet setWithObjects: @"Alpha", @"Beta", @"Gamma", @"X", nil];  
  3. NSString *string = @"gamma";  
  4.    
  5. [aSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {  
  6.     if ([obj localizedCaseInsensitiveCompare:string] == NSOrderedSame) {  
  7.         *stop = YES;  
  8.         found = YES;  
  9.     }  
  10. }];  
  11.    
  12. // At this point, found == YES  

拷貝Blocks

通常而言,你沒有表去copy(或retain)一個block. 除非你但願使用該block在當前聲明的範圍銷燬以後. 拷貝會將block移到堆(heap)中.

你可使用C函數去拷貝或釋放blocks:

 

C代碼    收藏代碼
  1. Block_copy();  
  2. Block_release();  
 

 

若是你正在使用Objective-C, 你能夠向block對象發送  copyretain, 和  release (也包括  autorelease) 消息.

爲了不內存泄露, Block_copy() 和Block_release()必需要對應使用. 一樣的也要對應 copy 或 retain 和 release (或 autorelease)的使用.除非是在垃圾回收的環境.

應避免的作法

block文本(即, ^{ ... }) 是表示block的局部棧數據結構(stack-local data structure)的地址. 因此這些棧數據僅在當前聲明的範圍內有效,必須避免以下的使用:

 

Objective-c代碼    收藏代碼
  1. void dontDoThis() {  
  2.     void (^blockArray[3])(void);  // an array of 3 block references  
  3.    
  4.     for (int i = 0; i < 3; ++i) {  
  5.         blockArray[i] = ^{ printf("hello, %d\n", i); };  
  6.         // WRONG: The block literal scope is the "for" loop  
  7.     }  
  8. }  
  9.    
  10. void dontDoThisEither() {  
  11.     void (^block)(void);  
  12.    
  13.     int i = random():  
  14.     if (i > 1000) {  
  15.         block = ^{ printf("got i at: %d\n", i); };  
  16.         // WRONG: The block literal scope is the "then" clause  
  17.     }  
  18.     // ...  
  19. }  

 

調試

 

你能夠在blocks中設斷點並單步跟蹤. 你也能夠在GDB裏直接用 invoke-block命令調用blocks,以下所示:

 

Shell代碼    收藏代碼
  1. $ invoke-block myBlock 10 20  
 

 

若是要傳遞C的字符串,你必須用引用括起來, 好比把  this string 傳給  doSomethingWithString block, 得這麼寫:
Shell代碼    收藏代碼
  1. $ invoke-block doSomethingWithString "\"this string\""  
   
 
相關文章
相關標籤/搜索