【转】objective-c 中代码块(blocks)

转自:http://blog.sina.com.cn/s/blog_67419c420100vl8b.html

 

    在ios4之后,引入了代码块的特性,在gcd中会经常的用到,所以决定好好的看看代码块文档,把这块总结一下。从头开始讲解代码块。

1.声明和使用代码块
一般用^操作符声明一个块变量,并作为块的开始符。而块的本身用{}包括起来,就像下面那样。
int multiplier = 7; 
int (^myBlock)(int) = ^(int num) { 
 return num * multiplier; 
}; 
下面的图是详细的讲解:

    其实意思就是前半句声明了一个名字为myBlock的代码块,有一个int类型的参数,并返回一个int类型的值;后面的半句就是一个块的定义,然后赋值给myBlock。
    如果我们像上面那样,声明一个块像一个变量一样,我们就可以像使用函数一样使用它,如下:
int multiplier = 7; 
int (^myBlock)(int) = ^(int num) { 
 return num * multiplier; 
}; 
 
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", "George", "TomJohn" } 
  一些cocoa frameworks的方法采用一个block作为一个参数,典型的是对一个集合对象进行操作,或者是在一个操作完成之后使用回调。下面的例子是NSArray类的方法 sortedArrayUsingComparator:怎样使用一个block。此方法使用一个block作为一个参数。
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); 
 
 
block的一个强大的功能是可以修改同一作用雨的变量,我们只需要在变量的前面加上一个_block标识符。下面的例子和上面的相同,只是添加功能用于记录相同元素的个数。
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); 
 
 
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
(1)调用一个声明好的block
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 

 

转载于:https://www.cnblogs.com/yencain/articles/2482603.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值