原文地址:
http://blog.sina.com.cn/s/blog_67419c420100vl8b.html
在ios4之后,引入了代码块的特性,在gcd中会经常的用到,所以决定好好的看看代码块文档,把这块总结一下。从头开始讲解代码块。
一般用^操作符声明
一个块变量,并作为块的开始符。而块的本身用{}
包括起来,就像下面那样。
int multiplier = 7; |
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};
下面的图是详细的讲解:
其实意思就是前半句声明了一个名字为myBlock的代码块,有一个int类型的参数,并返回一个int类型的值;后面的半句就是一个块的定义,然后赋值给myBlock。
如果我们像上面那样,声明一个块像一个变量一样,我们就可以像使用函数一样使用它,如下:
};
printf("%d",myBlock(3));
// prints "21"
2.直接使用block
在大多数情况下,我们不需要去声明
一个块变量,我们直接写
一个简单的
代码块作为参数传递就行。下面的
代码函数qsort_b的第三个参数就是
一个代码块。
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","TomJohn" }
NSArray *stringsArray = [NSArray arrayWithObjects:
@"string 1",
@"String 21",monospace"> @"string 12",monospace"> @"String 11",monospace"> @"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 = [stringsArraysortedArrayUsingComparator:finderSortBlock];
NSLog(@"finderSortArray: %@",finderSortArray);
block的
一个强大的
功能是可以
修改同一作用雨的变量,我们只需要在变量的前面
加上一个_block标识符。下面的例子和上面的相同,只是
添加功能用于记录相同元素的个数。
@"Strîng 21",monospace"> @"Striñg 21",monospace"> __block NSUInteger orderedSameCount = 0;
NSArray *diacriticInsensitiveSortArray = [stringsArray sortedArrayUsingComparator:^(id string1,id string2) {
NSComparisonResult comparisonResult = [string1 compare:string2 options:NSDiacriticInsensitiveSearch range:string1Range locale:currentLocale];
if (comparisonResult == NSOrderedSame) {
orderedSameCount++;
}
return comparisonResult;
}];
NSLog(@"diacriticInsensitiveSortArray: %@",diacriticInsensitiveSortArray);
NSLog(@"orderedSameCount: %d",orderedSameCount);
3.block变量的声明
block的声明和
函数指针差不多,只是把*改为了^
void (^blockReturningVoidWithVoidArgument)(void);
int (^blockReturningIntWithIntAndChararguments)(int,char);
void (^arrayOfTenBlocksReturningVoidWithIntArgument[10])(int);
也可以使用typedef去声明block,方便以后使用,如下:
typedef float (^MyBlockType)(float,float);
MyBlockType myFirstBlock = // ... ;
MyBlockType mySecondBlock = // ... ;
4.变量的作用域对于其在块中的影响:
_block int x = 123; // x lives in block storage
void (^printXAndY)(int) = ^(int y) {
x = x + y;
printf("%d %d\n",x,y);
printXAndY(456); // prints: 579 456
// x is Now 579
extern NSInteger CounterGlobal;
static NSInteger CounterStatic;
{
NSInteger localCounter = 42;
__block char localCharacter;
void (^aBlock)(void) = ^(void) {
++CounterGlobal;
++CounterStatic;
CounterGlobal = localCounter; // localCounter fixed at block creation
localCharacter = 'a'; // sets localCharacter in enclosing scope
++localCounter; // unseen by the block
localCharacter = 'b';
aBlock(); // execute the block
// localCharacter Now 'a'
}
5.使用blocks
int (^oneFrom)(int) = ^(int anInt) {
return anInt - 1;
printf("1 from 10 is %d",oneFrom(10));
// Prints "1 from 10 is 9"
float (^distanceTraveled) (float,float,float) =
^(float startingSpeed,float acceleration,float time) {
float distance = (startingSpeed * time) + (0.5 * acceleration * time * time);
return distance;
float howFar = distanceTraveled(0.0,9.8,1.0);
// howFar = 4.9