Objective-C-代码块Block回顾
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回顾的更多相关文章
- 04OC之分类Category,协议Protocol,Copy,代码块block
一.Protocol协议 我们都知道,在C#有个规范称之为接口,就是规范一系列的行为,事物.在C#中是使用Interface关键字来声明一个接口的,但是在OC中interface是用来声明类,所以用了 ...
- [转]iOS代码块Block
代码块Block是苹果在iOS4开始引入的对C语言的扩展,用来实现匿名函数的特性,Block是一种特殊的数据类型,其可以正常定义变量.作为参数.作为返回值,特殊地,Block还可以保存一段代码,在需要 ...
- iOS学习之代码块(Block)
代码块(Block) (1)主要作用:将一段代码保存起来,在需要的地方调用即可. (2)全局变量在代码块中的使用: 全局变量可以在代码块中使用,同时也可以被改变,代码片段如下: ;//注意:全局变量 ...
- 从C#到Objective-C,循序渐进学习苹果开发(4)--代码块(block)和错误异常处理的理解
本随笔系列主要介绍从一个Windows平台从事C#开发到Mac平台苹果开发的一系列感想和体验历程,本系列文章是在起步阶段逐步积累的,希望带给大家更好,更真实的转换历程体验.本文继续上一篇随笔<从 ...
- Objective-C-----协议protocol,代码块block,分类category
概述 ObjC的语法主要基于smalltalk进行设计的,除了提供常规的面向对象特性外,还增加了很多其他特性,本文将重点介绍objective-C中一些常用的语法特性. 当然这些内容虽然和其他高级语言 ...
- 代码块(block)的使用
Objective-C语法之代码块(block)的使用 代码块本质上是和其他变量类似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值. 脱 ...
- 一篇文章看懂iOS代码块Block
block.png iOS代码块Block 概述 代码块Block是苹果在iOS4开始引入的对C语言的扩展,用来实现匿名函数的特性,Block是一种特殊的数据类型,其可以正常定义变量.作为参数.作为返 ...
- Objective-C 代码块(block)的使用
代码块本质上是和其他变量类似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值. 脱字符(^)是块的语法标记.按照我们熟悉的参数语法规约所定 ...
- Objective-C语法之代码块(block)的使用
代码块本质上是和其它变量相似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你能够像调用其它标准函数一样,传入參数数,并得到返回值. 脱字符(^)是块的语法标记.依照我们熟悉的參数语法规约所定 ...
- 代码块(Block)回调一般阐述
本章教程主要对代码块回调模式进行讲解,已经分析其他回调的各种优缺点和适合的使用场景. 代码块机制 Block变量类型 Block代码封装及调用 Block变量对普通变量作用域的影响 Block回调接口 ...
随机推荐
- 洛谷P3605 [USACO17JAN] Promotion Counting 晋升者计数 [线段树合并]
题目传送门 Promotion Counting 题目描述 The cows have once again tried to form a startup company, failing to r ...
- 不可不说的Java“锁”事
前言 Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率.本文旨在对锁相关源码(本文中的源码来自JDK 8).使用场景进行举例,为读者介绍主流锁的知识点,以及不同的 ...
- 一个人也可以建立 TCP 连接呢
今天(恰巧是今天)看到有人在 SegmentFault 上问「TCP server 为什么一个端口可以建立多个连接?」.提问者认为 client 端就不能使用相同的本地端口了.理论上来说,确定一条链路 ...
- Splay和LCT的复杂度分析
\(Splay\)的复杂度分析 不论插入,删除还是访问,我们可以发现它们的复杂度都和\(splay\)操作的复杂度同阶,只是一点常数的区别 我们不妨假设有\(n\)个点的\(splay\),进行了\( ...
- 【字符串哈希】The 16th UESTC Programming Contest Preliminary F - Zero One Problem
题意:给你一个零一矩阵,q次询问,每次给你两个长宽相同的子矩阵,问你它们是恰好有一位不同,还是完全相同,还是有多于一位不同. 对每行分别哈希,先一行一行地尝试匹配,如果恰好发现有一行无法对应,再对那一 ...
- Codeforces Round #283 (Div. 2) A. Minimum Difficulty 暴力水题
A. Minimum Difficulty time limit per test 2 seconds memory limit per test 256 megabytes input standa ...
- webpack4 + vue + vue-router + vuex
ps: 所有案例使用的 node 及 npm 版本如下 node版本: v8.4.0 npm: 5.3.0 下一个案例默认是接着上一个继续写的 建议先熟悉以下文档 vue vue-router vue ...
- 最小生成树-克鲁斯卡尔算法(kruskal's algorithm)实现
算法描述 克鲁斯卡尔算法是一种贪心算法,因为它每一步都挑选当前最轻的边而并不知道全局路径的情况. 算法最关键的一个步骤是要判断要加入mst的顶点是否会形成回路,我们可以利用并查集的技术来做. 并查集的 ...
- angularjs中如何在异步请求执行完以后再执行其他函数?
angularjs中如何在异步请求执行完以后再执行其他函数? 之前脑袋回路就是从上到下的执行js,直到有一次我的页面上已经显示了空才走到angularjs里的$http的成功回调函数里,然后才开始正视 ...
- php远程获取图片或文件信息(get_headers,fsocketopen,curl)
<?php if(!function_exists("remote_filesize")){ /** * 获取远程或本地文件信息 * @param string $strUr ...