热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【转】blocks实践指南

转自:http:blog.sina.com.cnsblog_67419c420100vmkt.html 1.为什么要使用blocks将一个blocks作为函数或者方法的参数传递,可

转自:http://blog.sina.com.cn/s/blog_67419c420100vmkt.html

 

1.为什么要使用blocks

将一个blocks作为函数或者方法的参数传递,可以使函数或者方法在恰当的点实现回调。以各种NSNotification类为例子,传统的方法是一个对象添加自己作为此通知的观察者,实现处理接到通知应该调用的方法(通过addObserver....)。

如下:



































- (void)viewDidLoad {

[super viewDidLoad];

[[NSNotificationCenter defaultCenter] addObserver:self

selector:@selector(keyboardWillShow:)

name:UIKeyboardWillShowNotification object:nil];

}


- (void)keyboardWillShow:(NSNotification *)notification {

// Notification-handling code goes here.

}

然而通过方法 addObserverForName:object:queue:usingBlock: 我们也可以实现对通知的监控。

实现如下:


























- (void)viewDidLoad {

[super viewDidLoad];

[[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification

object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {

// Notification-handling code goes here.

}];

}

2.系统框架API中的blocks

另一个使用blocks的明显动机就是系统框架中提供了很多方法和函数用blocks作为参数。一般都存在于:

completion handlers,notification handlers,error handlers,enumeration,view animation and transitions,sorting 中,下面讲详细介绍。

(1)completion and Error handlers

     completion handlers是回调,其允许当框架方法或者函数完成任务时,在进行一些处理。多数情况下,用completion handler去free state 或者更新用户界面。很多框架方法让我们用blocks实现completion handlers,而不是代理方法或者notification handlers。

    UIView类有很多关于animation和view transitions的方法有completion handler block 参数。下面是animateWithDuration:animations:completion: 方法的一个实现例子。

- (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. sleep(3); self.imageView.frame = cacheFrame; self.imageView.alpha = 1.0; } }]; }

一些框架方法有error handlers,和completion handlers很相似。这些方法当其因为一些错误条件不能完成自己的任务的时候,调用这些error handlers blocks。我们典型的实现这些error handlers去通知用户出现错误。

(2)Notification handlers

   NSNotificationCenter的addObserverForName:object:queue:usingBlock:方法让我们去实现一个通知的handler去建立一个observation。下面是一个例子:
































- (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]);

}];

}

上面的方法要求传入一个NSOperationQueue实例,因此应用程序可以指定执行block handler 的execution context。

(3)Enumeration

   Foundation framework的集合类(NSArray ,NSDictionary, NSSet 和 NSIndexSet)声明了一些方法,可以用blocks来枚举整个集合,其实等价与下代码段:














for (id item in collection) {

// Code to operate on each item in turn.

}

    大概有两种形式。第一种方法名字以enumerate开始,没有返回值。

    第二种方法 block参数之前的名字为passingTest,这种方法返回整数或者一个NSIndexSet对象。这种方法的block一般是对迭代的每一个元素进行一个test,当test通过时返回YES。返回整数或者一个标识通过test的对象的集合。

   下面的代码对NSArray分别做了实例。一个方法的block返回数组中每个string有特定前缀的集合。


















































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);

    尽管NSString类不属于集合,但是它也有两个有block参数的方法,为enumerateSubstringsInRange:options:usingBlock:  enumerateLinesUsingBlock:。第一个方法的枚举单元可以是行,段,词,句,等等,但是第二个方法的就只是行。

下面的代码是使用block去匹配substring。









































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);

}

}];

(4)view animation 和 transitions

ios4.0之后UIView类引入了一些用于动画和view transitions的带block参数的方法。block参数分两类:

    block用于改变view的属性以完成动画。

    completion handlers。

下面的代码讲述了animateWithDuration:animations:completion:方法的用法。




















[UIView animateWithDuration:0.2 animations:^{

view.alpha = 0.0;

} completion:^(BOOL finished){

[view removeFromSuperview];

}];

这个动画就是让view逐渐消失,然后从父视图上移除。

  方法transitionWithView:duration:options:animations:completion:用于两个view的transitions,包括flips和curls。

下面的代码段实现了两个views 的flip transitions。























[UIView transitionWithView:containerView duration:0.2

options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{

[fromView removeFromSuperview];

[containerView addSubview:toView]

}

completion:NULL];

(5)sorting

foundation framework声明了NSComparator类型用于比较两个元素。

typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);

NSComparator是一个block类型,用于两个对象的比较,然后返回一个NSComparisonResult值。下面是一个例子:















































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]);

3.block 和concurrency

   block封装了一段代码,可以异步执行。基于这一事实,块可以用在GCD和NSOperationQueue上面。

   GCD函数dispatch_sync和函数dispatch_async的第二个参数就是用block。 



推荐阅读
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • Yii 实现阿里云短信发送 ... [详细]
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
  • MongoDB集群配置:副本集与分片详解
    本文详细介绍了如何在MongoDB中配置副本集(Replica Sets)和分片(Sharding),并提供了具体的步骤和命令,帮助读者理解并实现高可用性和水平扩展的MongoDB集群。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 本文介绍如何在QT框架中使用QWebSocket和QTcpSocket实现SSL加密通信,涵盖单向认证设置。单向认证常见于Web通信场景,其中客户端验证服务端证书,而服务端不验证客户端证书。 ... [详细]
  • 本文详细探讨了HTTP 500内部服务器错误的成因、解决方案及其在Web开发中的影响。通过对具体案例的分析,帮助读者理解并解决此类问题。 ... [详细]
  • 使用Vultr云服务器和Namesilo域名搭建个人网站
    本文详细介绍了如何通过Vultr云服务器和Namesilo域名搭建一个功能齐全的个人网站,包括购买、配置服务器以及绑定域名的具体步骤。文章还提供了详细的命令行操作指南,帮助读者顺利完成建站过程。 ... [详细]
author-avatar
壹花壹浄土
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有