本章的几节使用例子代码来开始块代码的学习。
定义和使用块代码
插入符^有两个作用,一个是声明一个块代码变量,另一个是开始一个块代码的定义。块代码的代码部分是包含在一对大括号中的,就像下面演示的这样(使用C语言风格的分号;作为块代码行的结束):
int multiplier = 7; |
int (^myBlock)(int) = ^(int num) { |
return num * multiplier; |
}; |
下图是对块代码的详细演示:
主义块代码中可以使用和它有同一个生存域的变量的。
如果你声明了一个块代码变量,你可以在后面像使用函数一样使用它:
int multiplier = 7; |
int (^myBlock)(int) = ^(int num) { |
return num * multiplier; |
}; |
printf("%d", myBlock(3)); |
// prints "21" |
直接使用块代码
很多情况下,你不需要声明块代码变量,你把一个块代码直接做内联实现,然后作为函数参数传入函数。下面的例子使用函数qsort_b
。
qsort_b和函数
qsort_r很像,不过它使用一个块代码作为参数。
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" } |
Cocoa中的块代码
Cocoa框架中有不少函数是使用块代码作为参数的,特别是在容器类中的包含对象的操作,或者一个操作完成后的回调函数。下面的例子演示了在NSArray类中的函数中使用块代码,这个函数仅有一个参数,就是这个块代码,为了演示,块代码被声明为NSComparator类型的本地变量:
NSArray *stringsArray = [NSArray arrayWithObjects: |
@"string 1", |
@"String 21", |
@"string 12", |
@"String 11", |
@"String 02", nil]; |
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); |
/* |
Output: |
finderSortArray: ( |
"string 1", |
"String 02", |
"String 11", |
"string 12", |
"String 21" |
) |
*/ |
__block类型变量
块代码的一个更强力的功能是可以修改具有同一可视周期的变量。当然你必须使用__block来修饰这个变量。考虑上节中的例子,如果我们需要使用一个变量来做一个统计,就像下例一样。这里的currentLocale变量对于代码块内部而言就是只读的。
NSArray *stringsArray = [NSArray arrayWithObjects: |
@"string 1", |
@"String 21", // <- |
@"string 12", |
@"String 11", |
@"Strîng 21", // <- |
@"Striñg 21", // <- |
@"String 02", nil]; |
NSLocale *currentLocale = [NSLocale currentLocale]; |
__block NSUInteger orderedSameCount = 0; |
NSArray *diacriticInsensitiveSortArray = [stringsArray sortedArrayUsingComparator:^(id string1, id string2) { |
NSRange string1Range = NSMakeRange(0, [string1 length]); |
NSComparisonResult comparisonResult = [string1 compare:string2 options:NSDiacriticInsensitiveSearch range:string1Range locale:currentLocale]; |
if (comparisonResult == NSOrderedSame) { |
orderedSameCount++; |
} |
return comparisonResult; |
}]; |
NSLog(@"diacriticInsensitiveSortArray: %@", diacriticInsensitiveSortArray); |
NSLog(@"orderedSameCount: %d", orderedSameCount); |
/* |
Output: |
diacriticInsensitiveSortArray: ( |
"String 02", |
"string 1", |
"String 11", |
"string 12", |
"String 21", |
"Str\U00eeng 21", |
"Stri\U00f1g 21" |
) |
orderedSameCount: 2 |
*/ |
这个内容在中有更多细节描述。