Blocks Programming Topics

来源:互联网 发布:计算机机房网络管理 编辑:程序博客网 时间:2024/04/29 20:04

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Blocks/Articles/bxGettingStarted.html#//apple_ref/doc/uid/TP40007502-CH7-SW1

大致翻译下

声明和使用Block

使用^脱字符来声明Block,作为Block语法的开端。如下:

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"
直接使用Blcok

在很多情况下,不需要直接声明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中的Blocks

在Cocoa frameworks中,有许多方法把block作为一个参数,特别是在一系列对象中执行一个操作,或者在操作完成后使用回调。下面的代码显示了如何在NSArray的sortedArrayUsingComparator:的方法中使用block。这个方法需要一个block参数。下面的示例中,block被定义为NSComparator的本地变量:

NSArray *stringsArray = @[ @"string 1",                           @"String 21",                           @"string 12",                           @"String 11",                           @"String 02" ]; 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: (    "string 1",    "String 02",    "String 11",    "string 12",    "String 21")*/

__block变量

block一个强大特性是能修改在同一个作用域中的变量。使用__block来表示能修改变量。 Blocks with Cocoa的示例,下面的例子展示了使用block变量来计算有多少个字符串是相等的。

NSArray *stringsArray = @[ @"string 1",                          @"String 21", // <-                          @"string 12",                          @"String 11",                          @"Strîng 21", // <-                          @"Striñg 21", // <-                          @"String 02" ]; 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); /*Output: diacriticInsensitiveSortArray: (    "String 02",    "string 1",    "String 11",    "string 12",    "String 21",    "Str\U00eeng 21",    "Stri\U00f1g 21")orderedSameCount: 2*/

Declaring a Block Reference

下面都是有效的block变量的声明:

void (^blockReturningVoidWithVoidArgument)(void);int (^blockReturningIntWithIntAndCharArguments)(int, char);void (^arrayOfTenBlocksReturningVoidWithIntArgument[10])(int);
如果在多个地方使用到同一个block,可以声明它,如下:

typedef float (^MyBlockType)(float, float); MyBlockType myFirstBlock = // ... ;MyBlockType mySecondBlock = // ... ;

Creating a Block

float (^oneFrom)(float); oneFrom = ^(float aFloat) {    float result = aFloat - 1.0;    return result;};

下面的例子展示了使用本地非静态变量:

int x = 123; void (^printXAndY)(int) = ^(int y) {     printf("%d %d\n", x, y);}; printXAndY(456); // prints: 123 456
给blcok中的x赋值,如下,会导致错误:

int x = 123; void (^printXAndY)(int) = ^(int y) {     x = x + y; // error    printf("%d %d\n", x, y);};

如果想改变block中的变量,可以使用__block修饰符。

下面的代码,展示了使用了__block的变量:

__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


下面的例子,是在block中使用各种不同的变量类型:

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'}

使用Blocks

调用一个Block

如果你声明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

使用Block作为方法的参数

NSArray *array = @[@"A", @"B", @"C", @"A", @"B", @"Z", @"G", @"are", @"Q"];NSSet *filterSet = [NSSet setWithObjects: @"A", @"Z", @"Q", nil]; BOOL (^test)(id obj, NSUInteger idx, BOOL *stop); test = ^(id obj, NSUInteger idx, BOOL *stop) {     if (idx < 5) {        if ([filterSet containsObject: obj]) {            return YES;        }    }    return NO;}; NSIndexSet *indexes = [array indexesOfObjectsPassingTest:test]; NSLog(@"indexes: %@", indexes); /*Output:indexes: <NSIndexSet: 0x10236f0>[number of indexes: 2 (in 2 ranges), indexes: (0 3)]*/

__block BOOL found = NO;NSSet *aSet = [NSSet setWithObjects: @"Alpha", @"Beta", @"Gamma", @"X", nil];NSString *string = @"gamma"; [aSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {    if ([obj localizedCaseInsensitiveCompare:string] == NSOrderedSame) {        *stop = YES;        found = YES;    }}]; // At this point, found == YES

0 0
原创粉丝点击