转载请附上原文链接:http://blog.csdn.net/perfect_promise/article/details/7757746
介绍
Block对象是一个C级别的语法和运行机制。它与标准的C函数类似,不同之处在于,它除了有可执行代码以外,它还包含了与堆、栈内存绑定的变量。因此,Block对象包含着一组状态数据,这些数据在程序执行时用于对行为产生影响。你可以用Block来写一些可以传到API中的函数语句,可选择性地存储,并可以使用多线程。作为一个回调,Block特别的有用,因为block既包含了回调期间的代码,又包含了执行期间需要的数据。
作为Mac OS X v10.6 Xcode开发工具附带的工具,Block在GCC和Clang中同样可用。你能在Mac OS X v10.6 及其以上版本和iOS 4.0及其以上版本中使用Block。.Block的运行是开源的,因此你能在LLVM’s compiler-rt subproject repository里面找到它。Block也已经被提交到C标准工作组作为 N1370: Apple’s Extensions to C。 由于Objective-C 和 C++ 都是衍生自 C,block被设计为可同时兼容这三种语言。
你应该阅读这篇文档,去学习Block是什么,以及在C、C++和OC中如何使用Block使你的程序更加的高效和更易于维护。
声明和使用Block
用^操作符来声明一个Block变量,并指明Block述句的开始。Block的主体部分包含在 {}内,像下面的例子中一样(与C语法一样,“;”指明语句的结束):
int multiplier = 7; |
int (^myBlock)(int) = ^(int num) { |
return num * multiplier; |
}; |
注意:Block可以使用定义范围之内的任何变量。
如果你把Block声明为一个变量,你以后就可以像调用一个方法一样使用它:
int multiplier = 7; |
int (^myBlock)(int) = ^(int num) { |
return num * multiplier; |
}; |
|
printf("%d", myBlock(3)); |
// prints "21" |
直接使用Block
很多情况下,你不需要声明Block变量;你只是简单地写一个Block语句内联在需要使用它作为参数的地方。下面的例子使用了 qsort_b方法,
qsort_b方法与标准的qsort_r类似,只是用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" } |
Cocoa Block
Cocoa框架中有几个方法使用Block作为参数,通常是在执行对象的操作集合,或者操作完成后使用它作为回调。下面的例子向我们展示了
在NSArray
对象的方法sortedArrayUsingComparator:怎样使用Block
.。这个方法只有单一的参数,block被定义为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: ( |