简介
块对象是C语言级别的语法和运行特性。类似于标准C函数。除了可执行代码之外他们还可以把变量绑定到堆(heap)栈(stack)中去。因此块能维持一系列的状态(data),这些状态或数据会影响执行后的结果。
你可以在API传递、多线程中使用块函数表达式。最有用的是把块作为回调函数,因为在回调时可以携带代码和参数。在OS X10.6的Xcode开发工具上可以使用块,它使用GCC个Clang集成,你可以在OS X10.6以后或者IOS4.0以后的版本使用块,块运行时(block runtime)是开源的,可以在LLVM’s compiler-rt subproject repository中找到。块之前在C标准工作组( N1370: Apple’s Extensions to C)中提到过。由于Objective-c和c++都由C衍生而来,所以块都可以在这三种语言中使用。
你应该通过阅读这篇文档来学习如何在C、C++、objective-c中使用块。
文档组成
这篇文档包括以下章节:
- 开始使用块(包括了块的快速、实用、简介)
- 概念概述(包括了块的概念简介)
- 声明和创建块(包括了如何声明一个块变量和如何实现块)
- 块和变量(描述了块和变量的作用,定义了__block类型修饰符)
- 使用块(详解各种用法)
开始使用块
下面的部分将使用实例带你开始学习块
声明、使用块
我们使用 ^ 操作符去声明一个块变量的开始。块主体使用{}(本例使用C语言,结尾使用;)
int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};
注意,块可以使用同一作用域内定义的变量
如果你声明了一个块变量,你可以把它当做函数来使用:
int multiple = 7;
int (^myBlock)(int) = ^(int num){
return num * multiple;
};
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, l);
});
//myCharacters is now { "Charles Consuming", "George", "TomJohn" }
Cocoa和块
Cocoa frameworks有一些方法中使用块作用参数,典型的用在集合中执行操作,或者用于操作完成后的回调,下例展示了如何在NSArray的方法sortedArrayUsingComparator中使用块,这个方法只有一个块参数,这样块就变成NSComparator的局部变量了。
NSArray *stringArray = @[ @"string 1",
@"string 21",
@"string 12",
@"string 11",
@"string 02" ];
static NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch | NSNumericSearch | NSWidthInsensitiveSearch | NSForceOrderingSearch;
NSLocale *currentLocale = [NSLocal 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,你就可以在块的作用域内改变它的值,下例中你可以使用block的变量来计算有多少个字符串值相同,在块中使用currentLocale作为只读变量。
NSArray *stringsArray = @[ @"string 1",
@"string 21", // <-
@"string 12",
@"string 11",
@"string 21", // <-
@"string 21", // <-
@"string 02" ];
NSLocale *currentLocale = [NSLocal 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:NSDiacriticInsenstiveSearch range:string1Range locale:currentLocale];
if (comparisonResult == NSOrderSame) {
orderSameCount++;
}
return comparisonResult;
}];
NSLog(@"diacriticInsensitiveSortArray: %@", diacriticInsensitiveSortArray);
NSLog(@"orderedSameCount: %d", orderedSameCount);
/*
Output:
finderSortArray: (
"string 1",
"string 02",
"string 11",
"string 12",
"string 21",
"str\U00eeng 21",
"stri\U00f1g 21"
)
orderSameCount: 2
*/
更多细节请看以下章节 声明和创建块
等待继续更新…