GCD1:构建Block Objects
问题:
希望能够编写自己的 Block Objects 或与 iOS SDK 类使用 Block Objects。
讨论:
1.Block Objects 的对象可以内联或编码为独立的代码块。我们从后一种开始:
假设你在 Objective-C 中有一个方法,既能接受 NSInteger 类的 2 个整数值,又能通过两个相减返回两 者的差值作为 NSInteger:
- (NSInteger) subtract:(NSInteger)paramValue from:(NSInteger)paramFrom{ return paramFrom - paramValue; }
C函数:
NSInteger subtract(NSInteger paramValue, NSInteger paramFrom){ return paramFrom - paramValue; }
现在看看作为 Block Object 我们如何编码同样的功能:
NSInteger(^subtract)(NSInteger,NSInteger) = ^(NSInteger paramValue, NSInteger paramFrom){ return paramFrom - paramValue; }
再看一个例子:
C:
NSString* intToString (NSUInteger paramInteger){ return [NSString stringWithFormat:@"%lu", (unsigned long)paramInteger]; }
Block Object:
NSString* (^intToString)(NSUInteger) = ^(NSUInteger paramInteger){ NSString *result = [NSString stringWithFormat:@"%lu",(unsigned long)paramInteger]; return result; }
从上面可以看到独立Block Object最简单的形式为
void (^simpleBlock)(void) = ^{ /**/ };
总结其表达式为
返回值类型 (^函数名)(参数类型,参数类型...) = ^(参数类型+参数名,参数类型+参数名...){
}
2. Block Objets可以以完全相同的方式调用C函数,如果他们有任何参数,你可以像C函数那样传递参数;
任何返回值可以精确检索,就像检索 C 函数的返回值一样。例子:
//独立的Block Objects 代码
NSString* (^intToString)(NSUInteger) = ^(NSUInteger paramInteger){ NSString *result = [NSString stringWithFormat:@"%lu",(unsigned long)paramInteger]; return result; }; - (void) callIntToString{ NSString *string = intToString(10); //能够像函数一样调用
NSLog(@"string = %@", string); }
上面代码中,callIntToString方法中通过给intToString block传入一个参数10,并将 这个 block 的返回值放在一个 string 局部变量中.
3.
现在我们需要一个 Objective-C 方法:这个方法接受一个无符号的整数参数和一个 Block Object 作为参数。
无符号的整数参数很简单,但是我们如何才能调用这个必须接受一个和 intToString Block Object 相同类型的 Block Object 方法。首先我们 typedef 这个intToStringBlock Object 的签名, 这个签名会告诉编译器我们的 Block Object 会接受什么参数:
#import "AppDelegate.h" typedef NSString* (^IntToStringConverter)(NSUInteger paramInteger); //这个 typedef 告诉编译器 Block Objects 接受一个整数参数并且返回一个被 IntToString Converter 命名的标示符来展现的字符串。
现在我们继续来写一个 Objective-C 方法,它接受 一个整数和 IntToStringConverter 类型的 Block Object:
- (NSString *)convertIntToString:(NSUInteger)paramInteger usingBlockObject:(IntToStringConverter)paramBlockObject{ return paramBlockObject(paramInteger); }
调用上面的方法:
NSString *result = [self convertIntToString:123 usingBlockObject:^NSString *(NSUInteger paramInteger) { NSString *result = [NSString stringWithFormat:@"%lu",(unsigned long)paramInteger]; return result; }];
4.