Block对象
Block对象是一段代码。先给出一个Block对象的示例:
^{
NSLog(@"this is a demo");
}
是在一个花括号内的一套指令,但是它没有函数名,相应的位置只有一个符号。表示这段代码是一个Block对象。
和函数一样,Block对象也可以有实参和返回值,再给出一个Block对象的示例:
^(double dividend, double divisor){
double quotient = dividend / divisor;
return quotient;
}
这段代码中的Block对象有两个实参,类型都是double,还返回一个double类型的值。
Block对象可以被当成一个实参来传递给可以接受Block的方法,很多苹果的类都有可以接受block为实参的方法。
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSArray *originalString = @[@"SauerKraut",@"Raygun",@"Big Nerd Ranch",@"Mississpi"];
NSLog(@"original strings:%@",originalString);
NSMutableArray *devowelLizedString = [NSMutableArray array];
NSArray *vowels = @[@"a",@"e",@"i",@"o",@"u"];
}
return 0;
}
28.1使用Block对象
声明Block变量
/
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSArray *originalString = @[@"SauerKraut",@"Raygun",@"Big Nerd Ranch",@"Mississpi"];
NSLog(@"original strings:%@",originalString);
NSMutableArray *devowelLizedString = [NSMutableArray array];
NSArray *vowels = @[@"a",@"e",@"i",@"o",@"u"];
NSArray *oldStrings = [NSArray arrayWithObjects:@"SauerKraut",@"Raygun",@"Big Nerd Ranch",@"Mississpi", nil];
NSLog(@"old string:%@",oldStrings);
//第一种创建方式
// NSMutableArray *newStrings = [NSMutableArray array];
//
// void (^devowelizer)(id,NSUInteger,BOOL *);
// devowelizer = ^(id string,NSUInteger i,BOOL *stop){
// NSMutableString *newString = [NSMutableString stringWithString:string];
// for(NSString *s in vowels){
// NSRange fullRange = NSMakeRange(0, [newString length]);
// [newString replaceOccurrencesOfString:s
// withString:@""
// options:NSCaseInsensitiveSearch
// range:fullRange];
// }
// [devowelLizedString addObject:newString];
// };
//第二种创建方式
void (^devowelizer)(id,NSUInteger,BOOL *) = ^(id string,NSUInteger i, BOOL *stop){
NSMutableString *newString = [NSMutableString stringWithString:string];
for(NSString *s in vowels){
NSRange fullRange = NSMakeRange(0, [newString length]);
[newString replaceOccurrencesOfString:s
withString:@""
options:NSCaseInsensitiveSearch
range:fullRange];
}
[devowelLizedString addObject:newString];
};
}
return 0;
}
传递Block对象
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSArray *originalString = @[@"SauerKraut",@"Raygun",@"Big Nerd Ranch",@"Mississpi"];
NSLog(@"original strings:%@",originalString);
NSMutableArray *devowelLizedString = [NSMutableArray array];
NSArray *vowels = @[@"a",@"e",@"i",@"o",@"u"];
NSArray *oldStrings = [NSArray arrayWithObjects:@"SauerKraut",@"Raygun",@"Big Nerd Ranch",@"Mississpi", nil];
NSLog(@"old string:%@",oldStrings);
//第一种创建方式
// NSMutableArray *newStrings = [NSMutableArray array];
//
// void (^devowelizer)(id,NSUInteger,BOOL *);
// devowelizer = ^(id string,NSUInteger i,BOOL *stop){
// NSMutableString *newString = [NSMutableString stringWithString:string];
// for(NSString *s in vowels){
// NSRange fullRange = NSMakeRange(0, [newString length]);
// [newString replaceOccurrencesOfString:s
// withString:@""
// options:NSCaseInsensitiveSearch
// range:fullRange];
// }
// [devowelLizedString addObject:newString];
// };
//第二种创建方式
NSMutableArray *newStrings= [NSMutableArray array];
void (^devowelizer)(id,NSUInteger,BOOL *) = ^(id string,NSUInteger i, BOOL *stop){
NSMutableString *newString = [NSMutableString stringWithString:string];
for(NSString *s in vowels){
NSRange fullRange = NSMakeRange(0, [newString length]);
[newString replaceOccurrencesOfString:s
withString:@""
options:NSCaseInsensitiveSearch
range:fullRange];
}
[newStrings addObject:newString];
};
[oldStrings enumerateObjectsUsingBlock:devowelizer];
NSLog(@"new strings: %@",newStrings);
}
return 0;
}
enumerateObjectsUsingBlock:方法要求传入的Block对象的三个实参类型是固定的,第一个是对象指针,指向当前的对象,该指针类型是id,所以无论数组包含的是什么类型的对象,都可以将地址赋给该指针。
修改Blioc的代码,检查字符串是否包含字符y。如果有,则设置指针指向YES(会阻止Block对象进行枚举),终止枚举。
NSMutableArray *newStrings= [NSMutableArray array];
void (^devowelizer)(id,NSUInteger,BOOL *) = ^(id string,NSUInteger i, BOOL *stop){
NSRange yRange = [strring rangeOfString:@"y"
options:NSCaseInsensitiveSearch];
if(yRange.location != NSNotFound){
*stop = YES;
return;
}
typedef
Block对象的语法可能会比较复杂。通过使用第11章介绍过的typedef关键字,可以将某个Block对象定义为一个新类型。需要注意的是,不能再方法的实现代码中使用tyoedef。也就是说,应该在实现文件的顶部,活着头文件内使用typedef。在main.m中,添加以下代码。
#import <Foundation/Foundation.h>
typedef void(^ArrayEnumerationBlock)(id, NSUInteger, BOOL);
int main(int argc, const char * argv[]) {
28.2Block对象 vs 其他回调
第27章介绍过两种回调机制:委托机制,和通知机制。通过回调机制,程序能够在特定事件发生时调用制定方法。虽然以上两种回调机制能很好的完成任务,但是也有一个缺点,即回调的设置代码和回调方法的具体实现无法写在同一段代码中。而且者两段代码经常会隔很远,甚至出现在不同的文件中。
Block可以将与回调相关的代码写在同一段代码中,
深入学习Block对象
返回值
double (^divBlock)(double dividend,double divisor);
匿名block
int i;
i=5;
NSNumber *num = [NSNumber numberWithInt:i];
int i=5;
NSNumber *num = [NSNumber numberWithInt;i];
NSNumber *num = [NSNumber numberWithInt:5];
采用第三个方法吗就是匿名的传递一个整数。
网友评论