在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
OC中的代码块是iOS4.0+ 和Mac OS X 10.6+ 引进的对C语言的扩展,用来实现匿名函数的特性。类似于其他语言脚本语言或者编程语言中的闭包或者是Lambda表达式,可能第一眼看上去很怪异,不过开发的过程中会越来越多的用到Block,还是了解多一点比较好。Block方面的内容也有很多,本文从实际使用的角度大概讲一下Block的基本概念和实践。 首先看一个苹果官网的例子: int (^Multiply)(int, int) = ^(int num1, int num2) { return num1 * num2; }; int result = Multiply(7, 4); // Result is 28. 上面的代码定义了一个Block,类似于C#中的委托,int表示返回类型,^是关键标示符,(int,int)是参数类型,不过需要注意的,正常的方式是将返回类型用()包裹,这里是将Block的名称包裹,网上有一个类似的图片,大家可以参考一下:
Block除了能够定义参数列表、返回类型外,还能够获取被定义时的词法范围内的状态(将变量作为参数传递之后,可以修改之后返回).Block都是一些简短代码片段的封装,适用作工作单元,通常用来做并发任务、遍历、以及回调。下面看一个通知的例子: - (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; } - (void)keyboardWillShow:(NSNotification *)notification { // Notification-handling code goes here. } 以上是调用addServer方法的例子,不过也可以这么写: - (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { // Notification-handling code goes here. }]; } 苹果官网这个使用Block的例子如果第一次看可能不是那么好理解,如果仔细的看addServerName的定义发现: - (id <NSObject>)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block NS_AVAILABLE(10_6, 4_0); 其中Block参数定义的时候是这样的: (void (^)(NSNotification *note))block NS_AVAILABLE(10_6, 4_0) 括号包裹起来的内容,第一个是返回值类型,之后的用用括号包裹^,之后的 话才是传递类型,基于以上的理解,可以这么写: void(^MyBlock)(NSNotification *)=^(NSNotification *note){ note=nil; }; [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:MyBlock]; Block在苹果的API文档中随处看见其身影,常见的情况任务完成时回调处理,消息监听回调处理,错误回调处理,枚举回调,视图动画、变换,排序,比如说在NSDictionary中的方法中: - (void)enumerateKeysAndObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (^)(id key, id obj, BOOL *stop))block NS_AVAILABLE(10_6, 4_0); 任务完成时候的调用: - (IBAction)animateView:(id)sender { CGRect cacheFrame = self.imageView.frame; [UIView animateWithDuration:1.5 animations:^{ CGRect newFrame = self.imageView.frame; newFrame.origin.y = newFrame.origin.y + 150.0; self.imageView.frame = newFrame; self.imageView.alpha = 0.2; } completion:^ (BOOL finished) { if (finished) { // Revert image view to original. self.imageView.frame = cacheFrame; self.imageView.alpha = 1.0; } }]; } 通知机制中的处理: - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { opQ = [[NSOperationQueue alloc] init]; [[NSNotificationCenter defaultCenter] addObserverForName:@"CustomOperationCompleted" object:nil queue:opQ usingBlock:^(NSNotification *notif) { NSNumber *theNum = [notif.userInfo objectForKey:@"NumberOfItemsProcessed"]; NSLog(@"Number of items processed: %i", [theNum intValue]); }]; } 枚举数组的时候的调用: NSString *area = @"Europe"; NSArray *timeZoneNames = [NSTimeZone knownTimeZoneNames]; NSMutableArray *areaArray = [NSMutableArray arrayWithCapacity:1]; NSIndexSet *areaIndexes = [timeZoneNames indexesOfObjectsWithOptions:NSEnumerationConcurrent passingTest:^(id obj, NSUInteger idx, BOOL *stop) { NSString *tmpStr = (NSString *)obj; return [tmpStr hasPrefix:area]; }]; NSArray *tmpArray = [timeZoneNames objectsAtIndexes:areaIndexes]; [tmpArray enumerateObjectsWithOptions:NSEnumerationConcurrent|NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL *stop) { [areaArray addObject:[obj substringFromIndex:[area length]+1]]; }]; NSLog(@"Cities in %@ time zone:%@", area, areaArray); 也可以写一个Block在截取字符串,做一些自己需要的事情: NSString *musician = @"Beatles"; NSString *musicDates = [NSString stringWithContentsOfFile: @"/usr/share/calendar/calendar.music" encoding:NSASCIIStringEncoding error:NULL]; [musicDates enumerateSubstringsInRange:NSMakeRange(0, [musicDates length]-1) options:NSStringEnumerationByLines usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { NSRange found = [substring rangeOfString:musician]; if (found.location != NSNotFound) { NSLog(@"%@", substring); } }]; 视图动画和转换中的实践: [UIView animateWithDuration:0.2 animations:^{ view.alpha = 0.0; } completion:^(BOOL finished){ [view removeFromSuperview]; }]; 两个视图之间的动画: [UIView transitionWithView:containerView duration:0.2 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{ [fromView removeFromSuperview]; [containerView addSubview:toView] } completion:NULL]; 数组排序的实践: 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 finderSort = ^(id string1, id string2) { NSRange string1Range = NSMakeRange(0, [string1 length]); return [string1 compare:string2 options:comparisonOptions range:string1Range locale:currentLocale]; }; NSLog(@"finderSort: %@", [stringsArray sortedArrayUsingComparator:finderSort]); 当然关于Block究竟是如何实现的,内存中是如何定义,如何保存的可以参考:http://blog.csdn.net/jasonblog/article/details/7756763 参考资料:https://developer.apple.com/library/ios/featuredarticles/Short_Practical_Guide_Blocks/ |
请发表评论