代碼塊(Block)/閉包(closure) 是對C語言中函數(shù)的擴(kuò)展例证。
代碼塊兩種類的綁定:
自動綁定(automatic binding) 棧內(nèi)存
托管綁定(managed binding) 堆內(nèi)存
-
代碼塊和函數(shù)指針
函數(shù)指針的聲明:
void (*my_func)(void);
*
變成^
(冪符號)變成代碼塊定義:
void (^my_block)(void);
代碼塊展示:
int (^square_block)(int number) = ^(int number) {return (number * number);}; int result = square_block(5); printf("Result = %d\n", result);
等號前面是代碼塊的定義讯柔,而等號后面是實(shí)現(xiàn)內(nèi)容。一般形式:
<returntype> (^blockname)(list of arguments) = ^(arguments){ body; };
沒有參數(shù)時可以簡寫:
void (^theBlock)(void) = ^{ printf("Hello Blocks!\n"); };
-
使用代碼塊
代碼塊可以訪問與它相同的(本地)有效范圍內(nèi)聲明的變量。int value = 6; int (^multiply_block)(int number) = ^(int number) { return (value * number);}; value = 8; int result2 = multiply_block(7); printf("Result2 = %d\n", result2); // 是6*7,不是8*7
直接使用代碼塊
NSArray *array = [NSArray arrayWithObjects:@"Amir", @"Mishal", @"Irrum", @"Adam", nil];
NSLog(@"Unsorted Array %@", array);
NSArray *sorteArray = [array sortedArrayUsingComparator:^(NSString *objet1, NSString *object2) {
return [objet1 compare:object2];
}];
NSLog(@"Sorted Array %@", sorteArray);
- 使用
typedef
關(guān)鍵字
typedef double (^MKSampleMultiply2BlockRef)(double c, double d);
MKSampleMultiply2BlockRef multiply2 = ^(double c, double d) { return c * d; };
printf("%f, %f", multiply2(4, 5), multiply2(5,3));
typedef void (^MKSampleVoidBlockRef)(void);
typedef void (^MKSampleStringBlockRef)(NSString *);
-
代碼塊和變量
代碼塊被聲明后會捕捉創(chuàng)建點(diǎn)時的狀態(tài)。
代碼塊可以訪問函數(shù)用到的標(biāo)準(zhǔn)類的變量:- 全局變量垂寥,包括封閉范圍內(nèi)聲明的本地靜態(tài)變量。
- 全局函數(shù)
- 封閉范圍內(nèi)的參數(shù)
- 函數(shù)級別(即與代碼塊聲明時相同的級別)的_block變量另锋。
- 封閉范圍內(nèi)的非靜態(tài)變量會被獲取為常量滞项。
- Objective-C的實(shí)例變量
- 代碼塊內(nèi)部的本地變量
-
本地變量
typedef double (^MKSampleMultiplyBlockRef)(void); double a = 10, b = 20; MKSampleMultiplyBlockRef multiply = ^(void){ return a * b; }; NSLog(@"%f", multiply()); // 200.0 a = 20; b = 50; NSLog(@"%f", multiply()); // 200.0
-
全局變量
typedef double (^MKSampleMultiplyBlockRef)(void); static double a = 10, b = 20; MKSampleMultiplyBlockRef multiply = ^(void){ return a * b; }; NSLog(@"%f", multiply()); // 200.0 a = 20; b = 50; NSLog(@"%f", multiply()); // 1000.0
-
參數(shù)變量
代碼塊中的參數(shù)變量與函數(shù)中的參數(shù)變量具有同樣的作用。typedef double (^MKSampleMultiply2BlockRef)(double c, double d); MKSampleMultiply2BlockRef multiply2 = ^(double c, double d) { return c * d; }; printf("%f, %f", multiply2(4, 5), multiply2(5,3));
-
__block
變量
本地變量會被代碼塊作為常量獲取到夭坪。在代碼塊中修改會報錯文判。double c = 3; MKSampleMultiplyBlockRef multiply = ^(void) { c = 5; return c; }; //報錯: Variable is not assignable (missing __block type specifier)
將本地變量標(biāo)記為
__block
,就可以修改了__block double c = 3; MKSampleMultiplyBlockRef multiply = ^(void) { c = 5; return c; };
代碼塊內(nèi)部的本地變量
關(guān)于Block詳細(xì)可查看Apple 的官方文檔 Blocks Programming Topics