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. Linux signal 编程(转载)

    转载地址:http://blog.sina.com.cn/s/blog_4b226b92010119l5.html 当服务器close一个连接时,若client端接着发数据.根据TCP协议的规定,会收 ...

  2. The file will have its original line endings in your working directory.

    在空仓库的情况下,add,出现一下问题 The file will have its original line endings in your working directory. 当报这个警告时是 ...

  3. (五)静态断言(下),static_assert

    二.静态断言与static_assert 通过上一篇,我们可以看到,断言assert宏只有在程序运行的时候才能起作用.而#error值在编译器预处理时才能起作用. 有时候,我们希望在编译时候能做一些断 ...

  4. MySQL Hash索引和B-Tree索引的区别

    MySQL Hash索引和B-Tree索引的区别究竟在哪里呢?相信很多人都有这样的疑问,下文对两者的区别进行了详细的分析,供您参考. MySQL Hash索引结构的特殊性,其检索效率非常高,索引的检索 ...

  5. hihocoder#1046 K个串 可持久化线段树 + 堆

    首先考虑二分,然后发现不可行.... 注意到\(k\)十分小,尝试从这里突破 首先用扫描线来处理出以每个节点为右端点的区间的权值和,用可持久化线段树存下来 在所有的右端点相同的区间中,挑一个权值最大的 ...

  6. bzoj 1176

    收获: 1.min, max, sum, 属于判定,等询问是”对象对答案贡献独立“,即不需要其他对象就了能更新答案,并保证只要所有对象更新过答案,那么该答案就是正确的.大概这就是所谓的”修改独立“. ...

  7. bzoj 2011

    决策单调性,对于一个1D/1D(状态是一维,转移也是一维)的DP,如果DP的决策具有单调性,那么就可以做到O(nlogn)的复杂度完成DP. 感谢<1D/1D  动态规划优化初步>的作者. ...

  8. python数据库操作——sqlite3模块

    # -*- coding: utf-8 -*- ''' Version : Python27 Author : Spring God Date : 2012-4-26 ''' import sqlit ...

  9. RTSP交互过程

    步骤一: 发送:OPTIONS rtsp://127.0.0.1/172.30.31.225:8000:HIK-DS8000HC:0:1:admin:hs123456:av_stream RTSP/1 ...

  10. ROS知识(11)----同步两台机器时钟

    两台机器同时运行过程中,对于ROS的tf变换,其要求两台机器的时钟要保持一致. 1.查询时间 首先通过以下命令,看两台机器时钟是否有差异.在本机上,查看远程master的机器时间: ntpdate - ...