Block介绍
一:Block是一种具有匿名功能的内嵌函数,特性如下:
(1):如一般函数能拥有带有型态的参数
(2):拥有回传值
(3):可以获取和选择性地修改作用域的状态
二:Block的使用
Block可以简化代码块,适合用来建立一些同步执行的代码,封装一些小型的工作或是作为某项工作完成时的回传呼叫。
三:声明和创建Block;
(1)用^来声明变量:返回值/声明方法/参数
1: /* 回传void ,参数也是void 的block*/
2: void (^blockReturningVoidWithVoidArgument)( void );
3: /* 回传整数,两个参数分别是整数和字元型态的block*/
4: int (^blockReturningIntWithIntAndCharArguments)( int , char );
5: /* 回传void ,含有10 个block 的阵列,每个block 都有一个型态为整数的参数*/
6: void (^arrayOfTenBlocksReturningVoidWinIntArgument[ 10 ])( int );
7: X.3.2 建立一个Block
8:
9: 我们使用「^」来开始一个block,并在最后使用「;」来表示结束,下面的范例示范了一个block变数,然后再定义一个block把它指定给block变数:
10:
11: int (^oneFrom)( int ); /* 宣告block 变数*/
12: /* 定义block 的内容并指定给上面宣告的变数*/
13: oneFrom = ^(int anInt)
14: {
15: return anInt = - 1 ;
16: };
(2)我们可以声明一个全局的block;
1: int GlobalInt = 0 ;
2: int (^getGlobalInt)( void ) = ^ ( void ) { return GlobalInt ;};
四:Block的使用(初级)
1: int multiplier = 7 ;
2: int (^myBlock)( int ) = ^( int num)
3: {
4: return num * multiplier;
5: };
6: printf ( "%d" , myBlock( 3 ));
7: //结果会打印出21
说明:
(1):声明一个myblock变量,用^符号表示这是一个block
(2):表示myblock是一个返回值为 int 的block
(3) : 他有一个参数,型态为整形,参数名为 num
直接使用Block:多数情况下,我们并不需要声明block变量。我们可以直接在需要使用block的地方直接用内嵌的方式将block的内容写出来,直接将block作为它的参数;
1: char *myCharacters[ 3 ] = { "TomJohn" , "George" , "Charles Condomine" };
2: qsort_b (myCharacters, 3 ,
3: sizeof ( char *),
4: ^( const void *l, const void *r)//block部分
5: {
6: char *left = *( char **)l;
7: char *right = *( char **)r;
8: return strncmp (left, right, 1 );
9: } //end
10: );
备注:如果修改内容的block,在前面添加__block int name;
五:__block变量 若要内部可以访问修改不许添加关键字
1: // 加上__block 修饰词,所以可以在block 中被修改。
2: __block int x = 123 ;
3: void (^printXAndY)( int ) = ^( int y)
4: {
5: x = x + y;
6: printf ( "%d %d\n" , x, y);
7: };
8: // 将会印出579 456
9: printXAndY( 456 );
10: //x 将会变成 579;
11: 下面我们使用一个范例来介绍各类型的变数和block之间的互动:
12:
13: extern NSInteger CounterGlobal;
14: static NSInteger CounterStatic;
15: {
16: NSInteger localCounter = 42 ;
17: __block char localCharacter;
18: void (^aBlock)( void ) = ^( void )
19: {
20: ++ CounterGlobal ; //可以存取。
21: ++ CounterStatic ; //可以存取。
22: CounterGlobal = localCounter; //localCounter在block 建立时就不可变了。
23: localCharacter = 'a' ; //设定外面定义的localCharacter 变数。
24: };
25: ++localCounter; //不会影响的block 中的值。
26: localCharacter = 'b' ;
27: aBlock(); //执行block 的内容。
28: //执行完后,localCharachter 会变成'a'
29: }
六:Block的使用
(1):声明一个block,直接使用block
1: int (^oneFrom)( int ) = ^( int anInt) {
2: return anInt - 1 ;
3: };
4: printf ( "1 from 10 is %d" , oneFrom( 10 ));
5: //结果会显示:1 from 10 is 9
6: float (^distanceTraveled)( float , float , float ) = ^( float startingSpeed, float acceleration, float time)
7: {
8: float distance = (startingSpeed * time) + ( 0.5 * acceleration * time * time);
9: return distance;
10: };
11: float howFar = distanceTraveled( 0.0 , 9.8 , 1.0 );
12: //howFar会变成4.9
(2):将block当作函数的参数
1: char *myCharacters[ 3 ] = { "TomJohn" , "George" , "Charles Condomine" };
2: qsort_b (myCharacters, 3 , sizeof ( char *),
3: ^( const void *l, const void *r)
4: {
5: char *left = *( char **)l;
6: char *right = *( char **)r;
7: return strncmp (left, right, 1 );
8: } // 这里是block 的终点。
9: );
10: // 最后的结果为:{"Charles Condomine", "George", "TomJohn"}
(3)将block当作方法的参数:我们可以像传递一般参数的方式传递block;
1: // 所有的资料
2: NSArray *array = [ NSArray arrayWithObjects : @"A" , @"B" , @"C" , @"A" , @"B" , @"Z" , @"G" , @"are" , @" Q" ,nil ];
3: // 我们只要这个集合内的资料
4: NSSet *filterSet = [ NSSet setWithObjects : @"A" , @"B" , @"Z" , @"Q" , nil ];
5: BOOL (^test)( id obj, NSUInteger idx, BOOL *stop);
6: test = ^ ( id obj, NSUInteger idx, BOOL *stop) {
7: // 只对前5 笔资料做检查
8: if (idx < 5 ) {
9: if ([filterSet containsObject : obj]) {
10: return YES ;
11: }
12: }
13: return NO ;
14: };
15: NSIndexSet *indexes = [array indexesOfObjectsPassingTest :test];
16: NSLog ( @"indexes: %@" , indexes);
17: // 结果:indexes: <NSIndexSet: 0x6101ff0>[number of indexes: 4 (in 2 ranges), indexes: (0-1 3-4)]
18: // 前5笔资料中,有4笔符合条件,它们的索引值分别是0-1, 3-4