[精通Objective-C]块(block)
来源:互联网 发布:python中定义矩阵 编辑:程序博客网 时间:2024/06/03 09:26
[精通Objective-C]块(block)
参考书籍:《精通Objective-C》【美】 Keith Lee
目录
- 精通Objective-C块block
- 目录
- 块的语法
- 块的词汇范围
- 块的内存管理
- 块的使用
- 使用块为数组排序
- 使用块的并行编程方式
块的语法
块是一个实现的闭包,一个允许访问其常规范围之外变量的函数。此外,一个Objective-C块实际上就是一个对象,它是NSObject类的子类,拥有NSObject类的相关属性。
块的声明:
int (^oneParamBlock)(int); // 声明一个名为oneParamBlock的块,该块接收一个int型参数,返回值也是int型的 void (^twoParamBlock)(int,int); // 接收两个int型参数,无返回值 void (^twoParamBlock2)(int parm1, int parm2); // 声明中可以含有参数名称 int (^noParamBlock)(void); // 没有参数需要写上void,不能省略
块的定义和调用:
// 将块常量赋值给之前声明的块(参数与返回值类型均需一致) oneParamBlock = ^(int addend){ return addend + 1; }; // 将块的声明和定义组合到一起(如果块常量没有参数,可以省略) void (^noParamBlock2)(void) = ^{ NSLog(@"Hello,World!"); }; // 块的调用 int value = oneParamBlock(5); NSLog(@"%d",value); // 定义并调用块表达式 ^(NSString *user){ NSLog(@"Greetings,%@!",user); }(@"Earthing");
将块常量表达式用作调用方法的参数:
// 创建一个名为AdderBlock的块类型用作方法中的参数类型typedef int (^AdderBlock)(int);@interface Calculator : NSObject-(int)process:(int)count withBlock:(AdderBlock)adder;@end@implementation Calculator-(int)process:(int)count withBlock:(AdderBlock)adder{ return adder(count);}@end
Calculator *clac = [Calculator new]; int result = [clac process:2 withBlock:^int(int addend) { return addend + 1; }]; NSLog(@"%d",result);
块的词汇范围
局部变量的声明需要放在使用该局部变量的块之前。默认情况下,块常量表达式中不能对局部变量进行修改,使用__block
修改符可以将这些变量切换为读写模式,但__block
修改符不能与auto、register和static组合使用。
int myVar = 10; void (^logValueBlock)(void) = ^{ NSLog(@"Variable value = %d", myVar); }; logValueBlock(); __block int myVar2 = 10; void(^intBlock)(int) = ^(int amount){ myVar2 += amount; NSLog(@"New value = %d", myVar2); }; intBlock(5);
块的内存管理
在运行程序时,块常量表达式会获得栈内存,因而会拥有与局部变量相同的生命周期。因此它们必须被复制到永久存储区域(即堆)中,才能定义它们的范围之外使用。例如,如果你想要从方法获得类型为块常量的返回值或者存储块常量,就必须将块复制到堆中并在不再使用它们时释放这些块。
在MRR内存管理方式中,块的copy和release需要达到平衡
void (^greetingBlock)(void); { greetingBlock = [^{ NSLog(@"Hello,World!"); } copy]; } greetingBlock(); [greetingBlock release]; // 释放块,防止内存泄漏
而在ARC内存管理方式中,编译器会自动执行块的复制和释放操作
块的使用
下面是两个使用块的例子:
使用块为数组排序
#import <Foundation/Foundation.h>#include <stdlib.h>#define ArrayElements 10int main(int argc, const char * argv[]) { @autoreleasepool { // 创建一个含有随机数值(0~99)的数组 NSMutableArray *numbers = [NSMutableArray arrayWithCapacity: ArrayElements]; for (int elem = 0; elem < ArrayElements; elem++) { unsigned int value = arc4random() % 100; [numbers addObject:[NSNumber numberWithUnsignedInt:value]]; } NSLog(@"Values:%@",numbers); // 记录未排序的数值 // 以升序方式为数组数值排序 [numbers sortUsingComparator:^(id obj1, id obj2){ if ([obj1 integerValue] > [obj2 integerValue]) { return (NSComparisonResult)NSOrderedDescending; } if ([obj1 integerValue] < [obj2 integerValue]) { return (NSComparisonResult)NSOrderedAscending; } return (NSComparisonResult)NSOrderedSame; }]; NSLog(@"Values:%@",numbers); //记录未排序的数值 } return 0;}
使用块的并行编程方式
#import <Foundation/Foundation.h>#define YahooURL @"http://www.yahoo.com/index.html"#define ApressURL @"http://www.apress.com/index.html"typedef void (^DownloadURL)(void);// 获取用于下载URL的块DownloadURL getDownloadURL(NSString *url){ NSString *urlString = url; return ^{ // 下载URL NSDate *startTime = [NSDate date]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]; NSError *error; // 注意,NSURLConnection在iOS9中已被废除,推荐使用NSURLSession,后面有NSURLSession的使用方法 NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error]; if (data == nil) { NSLog(@"Error loading request %@",[error localizedDescription]); } else{ NSDate *endTime = [NSDate date]; NSTimeInterval timeInterval = [endTime timeIntervalSinceDate:startTime]; NSLog(@"Time taken to download %@ = %f seconds", urlString, timeInterval); } };}int main(int argc, const char * argv[]) { @autoreleasepool { // 创建任务请求 dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_queue_t queue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 创建任务分组 dispatch_group_t group = dispatch_group_create(); // 获取度量的当前时间 NSDate *startTime = [NSDate date]; // 创建并分派异步任务 dispatch_group_async(group, queue1, getDownloadURL(YahooURL)); dispatch_group_async(group, queue2, getDownloadURL(ApressURL)); // 等待,直到分组中的所有任务完成为止 dispatch_group_wait(group, DISPATCH_TIME_FOREVER); // 为并行操作和日志检索时间信息 NSDate *endTime = [NSDate date]; NSTimeInterval timeInterval = [endTime timeIntervalSinceDate:startTime]; NSLog(@"Time taken to download URLs concurrently = %f seconds", timeInterval); } return 0;}
使用NSURLSession:
// NSURLSession在命令行程序中可能无法正常使用,可以在iOS环境下调试 NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSLog(@"123"); if (data == nil) { NSLog(@"Error loading request %@",[error localizedDescription]); } else{ NSDate *endTime = [NSDate date]; NSTimeInterval timeInterval = [endTime timeIntervalSinceDate:startTime]; NSLog(@"Time taken to download %@ = %f seconds", urlString, timeInterval); } }]; [dataTask resume];
运行结果:
2016-07-14 16:03:50.780 BlockConcurrentTasks[20262:170183] Time taken to download http://www.apress.com/index.html = 1.259164 seconds2016-07-14 16:03:54.485 BlockConcurrentTasks[20262:170182] Time taken to download http://www.yahoo.com/index.html = 4.965020 seconds2016-07-14 16:03:54.486 BlockConcurrentTasks[20262:170152] Time taken to download URLs concurrently = 4.965577 seconds
可以看出并行方式执行任务的时间比以异步方式所消耗的时间更少。
2 0
- [精通Objective-C]块(block)
- Objective-C block (块)
- Objective-C block(代码块)
- Objective-C - 代码块block
- 【Objective-C】代码块(Block)
- Objective-c的block(块)
- Objective C基础(八)---Block代码块
- Objective-C语法之代码块(block)的使用
- Objective-C代码块(block)的练习
- objective-c-block 块
- Objective-c中的Block(块)详解
- [objective-C] 05.Block块语法
- Objective-C中的block代码块介绍
- Objective-C block块与函数指针
- Objective-C代码块Block详解
- Objective-C语言——Block块
- Objective-C 14 代码块Block
- object-c块(block)
- 【阅读】《黑客与画家》系列07-设计与研究(节选)
- 51nod 1119 机器人走方格
- Web自动化测试相关知识点(仅限于补充)
- Android提高之Android手机与BLE终端通信
- 大家好,我是新人
- [精通Objective-C]块(block)
- 在activity中使用ViewFlipper实现广告自动滑页和每一页的广告的点击事件
- GIT学习(三)_远程仓库(GITHUB)
- HBase内置过滤器
- 数据库设计原则
- Linux利用socket实现两台pc之间的数据传输功能,包括windows到linux,UDP实现
- 在线二维码图片生成器
- Memcached实现Session的分布式存储
- 实现页面倒数秒后跳转到指定页面