Block對象是一個C底層的語法和運行時特性,它和標準的C函數有點相似,但除了可執行的代碼它們包含變量自動綁定?;蛟诙褍裙芾韮却?。因此塊可以維護一系列的狀態-當執行時用于影響它的行為。
你可以使用塊去結合被傳給API的函數表達式,額外儲存 和被多線程使用。Block作為回調是十分有用的,因為Block都攜帶被執行的代碼在回調時,并且在執行期間數據是必須的。
Block在GCD和Clang是可用的,block運行時是開源的,在相關網站可以找到關于這個的有關內容。
1,聲明和使用blocks
你可以用……操作符去聲明block變量今兒提示block字面值的開頭。block自身的body在{}內,例如
int multiplier = 12;
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};
Note:int 指的是block的返回值類型,^表示這是一個block,而myBlock則表示聲明了一個變量*myBlock,而num則指的是帶一個參數,而{}內則是block的body。這是一個完整的block聲明與使用的例子。
2,直接使用blocks
在許多時間中,不必聲明block變量,相反你在要求作為參數的地方寫一個塊內聯。
char *myCharacters[3] = { "TomJohn", "George", "Charles Condomine" };
qsort_b(myCharacters, 3, sizeof(char *), ^(const void *l, const void *r) {
char *left = *(char **)l;
char *right = *(char **)r;
return strncmp(left, right, 1);
});
// myCharacters is now { "Charles Condomine", "George", "TomJohn" }
3,塊與cocoa
在cocoa 框架中,一系列的方法帶塊作為一個參數,典型的要么去在對象的集合上去實現操作 要么在一個操作完成后作為一個回調使用,下面的例子展示如何使用帶有sortedArrayUsingComparator:的塊
NSArray *stringsArray = @[@"string1",@"string3",@"string4",@"string5"];
static NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch | NSNumericSearch | NSWidthInsensitiveSearch | NSForcedOrderingSearch;
NSLocale *currentLocale = [NSLocale currentLocale];
NSComparator finderSortBlock = ^(id string1,id string2) {
NSRange string1Range = NSMakeRange(0, [string1 length]);
return [string1 compare:string2 options:
comparisonOptions range:string1Range locale:currentLocale];
};
NSArray *finderSortArray = [stringsArray sortedArrayUsingComparator:finderSortBlock];
NSLog(@"finderSortArray:%@",finderSortArray);
結果如下所示:
finderSortArray:(
string1,
string3,
string4,
string5
)
塊概念上的綜述
塊對象給我們提供了一個方式去在C語言和C衍生的語言中生成一個特殊的函數體作為表達式,例如OC,C++。在其他語言和環境中,一個塊對象有時候被稱之為閉包
Block的功能
只有了解了功能,你才能找到對應的場景去使用它。
一個塊是代碼的一個匿名內聯集合-有一個類型參數列表正如一個函數,有一個推斷或聲明的返回值類型,能在它定義的詞法作用域內捕捉狀態,能額外的修改詞法作用域內的狀態,能在相同的詞法作用域內,可以分享潛在的修改與其他模塊中定義相同的詞法作用域可以繼續分享和詞法作用域內定義的修改狀態后(堆棧幀)詞法作用域(堆棧幀)已經被摧毀了你可以復制一個街區,甚至將其傳遞給其他線程對延遲執行(或者,在它自己的線程,runloop)。編譯器和運行時安排所有變量引用塊保存的所有副本的生活。盡管塊可用純C和c++,一塊也總是一個objective - C對象。
block的使用
塊代表通常很小,具有獨立的代碼塊。這樣,他們特別有用的封裝的工作單元可能并發執行,或在項目集合,或者作為回調當另一個操作完成。塊是一個有用的替代傳統的回調函數,主要有兩個原因:他們允許你編寫代碼的調用方法的上下文中執行后實現。塊因此經??蚣芊椒ǖ膮怠K麄冊试S訪問本地變量。而不是使用回調函數需要一個數據結構,包含了所有你需要的上下文信息來執行一個操作,只需直接訪問本地變量。
聲明使用
您還可以創建類型blocks-這樣做所以通常被認為是最佳實踐,當你使用一塊與給定的簽名在多個地方:例如
typedef float (^MyBlockType)(float, float);
MyBlockType myFirstBlock = // ... ;
MyBlockType mySecondBlock = // ... ;
Block和變量
塊對象的身體內的代碼,變量可能被視為五個不同的方法。你可以參考三種標準類型的變量,就像從一個函數:全局變量,包括靜態局部變量全局函數(這不是技術變量)從一個封閉范圍局部變量和參數塊也支持兩個其他類型的變量:在功能層面上是__block變量。這些是可變塊內(和封閉范圍)和保存如果任何引用塊復制到堆。const進口。最后,在一個方法的實現,模塊可能variables-see objective - c實例對象的引用和塊變量。以下規則適用于變量中使用一塊:訪問全局變量,包括封閉詞法作用域內存在的靜態變量。參數傳遞給塊訪問(就像參數函數)。本地堆棧(非靜態)變量封閉詞法作用域為常量變量捕獲。它們的值是在計劃內的塊表達式。在嵌套塊,價值捕獲從最近的封閉范圍。局部變量的封閉詞法作用域聲明__block存儲修改器提供參考,因此是可變的。反映在封閉詞法作用域的任何更改,包括任何其他模塊中定義相同的封閉詞法范圍。更詳細地討論這些__block存儲類型。局部變量聲明的詞法作用域內,局部變量在函數的完全一樣。每個調用塊提供了一個新的變量的副本。這些變量可以作為常量或按引用調用變量在街區內封閉塊中。