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/

Objective-C-代码块Block回顾的更多相关文章

  1. 04OC之分类Category,协议Protocol,Copy,代码块block

    一.Protocol协议 我们都知道,在C#有个规范称之为接口,就是规范一系列的行为,事物.在C#中是使用Interface关键字来声明一个接口的,但是在OC中interface是用来声明类,所以用了 ...

  2. [转]iOS代码块Block

    代码块Block是苹果在iOS4开始引入的对C语言的扩展,用来实现匿名函数的特性,Block是一种特殊的数据类型,其可以正常定义变量.作为参数.作为返回值,特殊地,Block还可以保存一段代码,在需要 ...

  3. iOS学习之代码块(Block)

    代码块(Block) (1)主要作用:将一段代码保存起来,在需要的地方调用即可. (2)全局变量在代码块中的使用: 全局变量可以在代码块中使用,同时也可以被改变,代码片段如下: ;//注意:全局变量 ...

  4. 从C#到Objective-C,循序渐进学习苹果开发(4)--代码块(block)和错误异常处理的理解

    本随笔系列主要介绍从一个Windows平台从事C#开发到Mac平台苹果开发的一系列感想和体验历程,本系列文章是在起步阶段逐步积累的,希望带给大家更好,更真实的转换历程体验.本文继续上一篇随笔<从 ...

  5. Objective-C-----协议protocol,代码块block,分类category

    概述 ObjC的语法主要基于smalltalk进行设计的,除了提供常规的面向对象特性外,还增加了很多其他特性,本文将重点介绍objective-C中一些常用的语法特性. 当然这些内容虽然和其他高级语言 ...

  6. 代码块(block)的使用

    Objective-C语法之代码块(block)的使用 代码块本质上是和其他变量类似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值. 脱 ...

  7. 一篇文章看懂iOS代码块Block

    block.png iOS代码块Block 概述 代码块Block是苹果在iOS4开始引入的对C语言的扩展,用来实现匿名函数的特性,Block是一种特殊的数据类型,其可以正常定义变量.作为参数.作为返 ...

  8. Objective-C 代码块(block)的使用

    代码块本质上是和其他变量类似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值. 脱字符(^)是块的语法标记.按照我们熟悉的参数语法规约所定 ...

  9. Objective-C语法之代码块(block)的使用

    代码块本质上是和其它变量相似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你能够像调用其它标准函数一样,传入參数数,并得到返回值. 脱字符(^)是块的语法标记.依照我们熟悉的參数语法规约所定 ...

  10. 代码块(Block)回调一般阐述

    本章教程主要对代码块回调模式进行讲解,已经分析其他回调的各种优缺点和适合的使用场景. 代码块机制 Block变量类型 Block代码封装及调用 Block变量对普通变量作用域的影响 Block回调接口 ...

随机推荐

  1. CSU - 2061 Z‘s Coffee

    Description Z is crazy about coffee. One day he bought three cups of coffee. The first cup has a cap ...

  2. 快递鸟电子面单打印功能基于java

    之前的后天管理系统的电子面单打印使用的是灵通打单. 使用相对比较麻烦,需要到处Excel之后再导入,麻烦. 快递鸟有电子面单api,后台系统直接对接很是方便,不过也遇到了好些问题. 不难是不难,但是遇 ...

  3. odoo打包下载

    view 视图中下载按钮的编辑 <record id="action_download_zip" model="ir.actions.server"> ...

  4. [SQL]197. Rising Temperature

    Given a Weather table, write a SQL query to find all dates' Ids with higher temperature compared to ...

  5. iOS Sprite Kit教程之xcode安装以及苹果帐号绑定

    iOS Sprite Kit教程之xcode安装以及苹果帐号绑定 其它的网站上下载安装Xcode 有时候,应用商店下载较慢,所以用户也可以选择从其他网站下载Xcode安装文件.下面讲解这种Xcode的 ...

  6. python学习笔记 - for循环: 遍历字典, 分别打印key, value, key:value

    #遍历字典, 分别打印key, value, key:value emp = {'name':'Tom', 'age':20, 'salary' : 8800.00} for k in emp.key ...

  7. luogu P2439 [SDOI2005]阶梯教室设备利用

    题目链接 luogu P2439 [SDOI2005]阶梯教室设备利用 题解 dp 代码 #include<vector> #include<cstdio> #include& ...

  8. [PE484]Arithmetic Derivative

    题意:对整数定义求导因子$'$:$p'=1,(ab)'=a'b+ab'$,求$\sum\limits_{i=2}^n(i,i')$ 这个求导定义得比较妙:$(p^e)'=ep^{e-1}$ 推一下就可 ...

  9. 网络抓包及Http Https通信协议分析

    Wireshark基本介绍和学习TCP三次握手 之前写过一篇博客:用 Fiddler 来调试HTTP,HTTPS. 这篇文章介绍另一个好用的抓包工具wireshark, 用来获取网络数据封包,包括ht ...

  10. Java-----jar反编译修改重新打包

    http://blog.csdn.net/hekewangzi/article/details/44676797 一.使用反编译工具JD-GUI(JD-GUI相关操作见Java-----反编译clas ...