obj-c编程09:块的语法
在obj-c中,有一种和C截然不同的东西——块。块可以在外边定义,也可以在函数或方法内部定义,可以被赋值给一个变量,然后用该变量调用。默认情况下块对外部变量的访问只能读不能写,除非用__block显示声明可写。对于块这么个东东,让我想到了ruby中的block,不过ruby中block是闭包,而且外部变量变化会影响block的值,但obj-c的块不会,即obj-c块的外部变量是编译时求值而不是运行时求值哦:
#import <Foundation/Foundation.h>
int main(int argc,char *argv[])
{
@autoreleasepool{
int i = 10;
//foo是一个块变量被赋值为一个块。
int (^foo)(int) = ^(int x) {
int ret = x * i;
//i = 100; 编译错误,不能改写外部变量的值
NSLog(@"%d * i(%d) = %d",x,i,ret);
return ret;
};
i = 1000;
foo(11); //i此时为10而不是1000哦。
}
return 0;
}
可以看到在块内是不能写外部i变量的,除非用__block修饰:
#import <Foundation/Foundation.h>
int main(int argc,char *argv[])
{
@autoreleasepool{
__block int i = 10;
//foo是一个块变量被赋值为一个块。
int (^foo)(int) = ^(int x) {
i = 100;
int ret = x * i;
NSLog(@"%d * i(%d) = %d",x,i,ret);
return ret;
};
i = 1000;
NSLog(@"ret is %d",foo(11)); //i此时为100哦。
}
return 0;
}
如果是在ruby中则外部变量变化会导致block的结果发生变化,也给个例子吧:
apple@kissAir: objc_src$irb
2.1.1 :001 > $v = 100
=> 100
2.1.1 :002 > b = ->(x){puts "#$v * #{x} = #{$v * x}"}
=> #<Proc:0x0000010182c0d8@(irb):2 (lambda)>
2.1.1 :003 > b[11]
100 * 11 = 1100
=> nil
2.1.1 :004 > $v=11
=> 11
2.1.1 :005 > b[11]
11 * 11 = 121
=> nil
[2014.07.06第一次新增内容]:块功能扩展
我们还可以用block来实现集合对象的map功能,比如ruby中数组或散列的map:
#import <Foundation/Foundation.h>
#define msg(...) NSLog(__VA_ARGS__)
NSArray *map(NSArray *ary,id (^block)(id))
{
NSMutableArray *ary_ret = [NSMutableArray array];
for(id x in ary)
[ary_ret addObject:block(x)];
return ary_ret;
}
int main(int argc,char *argv[])
{
@autoreleasepool{
NSArray *ary_init = [NSArray arrayWithObjects:@"big",@"small",\
@"love",@"pluck",@"save",nil];
NSArray *ary = map(ary_init,^(id item){\
return [item capitalizedString];});
msg(@"%@",ary);
}
return 0;
}
运行结果如下:
apple@kissAir: objc_src$./blk
2014-07-06 14:47:57.758 blk[1009:507] (
Big,
Small,
Love,
Pluck,
Save
)
块能做的事可不止这些哦,我们可以借助GCD中对块的支持并发的执行任务:
#import <Foundation/Foundation.h>
#define msg(...) NSLog(__VA_ARGS__)
int main(int argc,char *argv[])
{
@autoreleasepool{
NSMutableArray *ary_m = [NSMutableArray array];
//获取GCD全局队列
dispatch_queue_t g_queue = dispatch_get_global_queue(0,0);
//创建新的执行组
dispatch_group_t grp = dispatch_group_create();
srand(time(NULL));
__block int s = 0;
for(int i = 0;i < 1000;++i){
dispatch_block_t block = ^{
s = rand() % 5;
sleep(s);
msg(@"at %4d:sleeped %d s",i,s);
};
//在组中异步执行块
dispatch_group_async(grp,g_queue,block);
}
//等待组中所有块任务执行完毕
dispatch_group_wait(grp,DISPATCH_TIME_FOREVER);
}
return 0;
}
运行如下:
apple@kissAir: objc_src$./blk
2014-07-06 15:25:07.318 blk[1231:3903] at 19:sleeped 0 s
2014-07-06 15:25:07.318 blk[1231:3303] at 17:sleeped 0 s
2014-07-06 15:25:07.319 blk[1231:4703] at 21:sleeped 0 s
2014-07-06 15:25:07.319 blk[1231:4c03] at 22:sleeped 0 s
2014-07-06 15:25:07.319 blk[1231:4003] at 20:sleeped 0 s
2014-07-06 15:25:07.322 blk[1231:3e03] at 31:sleeped 0 s
2014-07-06 15:25:07.323 blk[1231:5e03] at 36:sleeped 0 s
2014-07-06 15:25:07.324 blk[1231:6403] at 40:sleeped 0 s
2014-07-06 15:25:07.325 blk[1231:6803] at 43:sleeped 0 s
2014-07-06 15:25:07.327 blk[1231:7a03] at 53:sleeped 0 s
2014-07-06 15:25:07.328 blk[1231:7a03] at 56:sleeped 0 s
2014-07-06 15:25:07.328 blk[1231:7a03] at 58:sleeped 2 s
2014-07-06 15:25:07.330 blk[1231:8a03] at 64:sleeped 0 s
2014-07-06 15:25:07.333 blk[1231:9e03] at 75:sleeped 0 s
2014-07-06 15:25:07.333 blk[1231:9e03] at 77:sleeped 0 s
2014-07-06 15:25:07.333 blk[1231:9e03] at 78:sleeped 0 s
2014-07-06 15:25:08.315 blk[1231:1903] at 4:sleeped 2 s
2014-07-06 15:25:08.315 blk[1231:1103] at 1:sleeped 2 s
2014-07-06 15:25:08.315 blk[1231:1503] at 3:sleeped 2 s
2014-07-06 15:25:08.315 blk[1231:1f03] at 7:sleeped 2 s
2014-07-06 15:25:08.315 blk[1231:2303] at 9:sleeped 2 s
2014-07-06 15:25:08.317 blk[1231:2f03] at 15:sleeped 2 s
2014-07-06 15:25:08.319 blk[1231:2303] at 84:sleeped 0 s
2014-07-06 15:25:08.323 blk[1231:4c03] at 28:sleeped 2 s
2014-07-06 15:25:08.323 blk[1231:5203] at 30:sleeped 2 s
2014-07-06 15:25:08.323 blk[1231:5803] at 32:sleeped 2 s
2014-07-06 15:25:08.323 blk[1231:5c03] at 35:sleeped 2 s
2014-07-06 15:25:08.324 blk[1231:5e03] at 38:sleeped 2 s
2014-07-06 15:25:08.324 blk[1231:6603] at 41:sleeped 2 s
2014-07-06 15:25:08.325 blk[1231:5203] at 88:sleeped 0 s
2014-07-06 15:25:08.325 blk[1231:6a03] at 44:sleeped 0 s
2014-07-06 15:25:08.325 blk[1231:5c03] at 90:sleeped 0 s
2014-07-06 15:25:08.325 blk[1231:6c03] at 46:sleeped 0 s
2014-07-06 15:25:08.326 blk[1231:7003] at 48:sleeped 1 s
2014-07-06 15:25:08.327 blk[1231:6a03] at 94:sleeped 0 s
2014-07-06 15:25:08.328 blk[1231:5c03] at 97:sleeped 0 s
2014-07-06 15:25:08.328 blk[1231:5c03] at 99:sleeped 0 s
2014-07-06 15:25:08.329 blk[1231:7a03] at 61:sleeped 3 s
2014-07-06 15:25:08.330 blk[1231:8c03] at 65:sleeped 3 s
2014-07-06 15:25:08.331 blk[1231:8c03] at 102:sleeped 0 s
2014-07-06 15:25:08.333 blk[1231:a003] at 76:sleeped 4 s
2014-07-06 15:25:08.333 blk[1231:9a03] at 73:sleeped 4 s
2014-07-06 15:25:08.334 blk[1231:9a03] at 105:sleeped 0 s
obj-c编程09:块的语法的更多相关文章
- 【Shell编程】Shell基本语法
Shell 语法 Shell程序设计作为一种脚本语言,在Linux系统中有广泛的应用,本文记录了关于Shell程序设计的基础语法知识和常用命令,方便查询,熟练使用shell也需要经常实践,这对于完 ...
- Python并行编程(八):with语法
1.基本概念 当有两个相关的操作需要在一部分代码块前后分别执行的时候,可以使用with语法自动完成.同时,使用with语法可以在特定的地方分配和释放资源,因此,with语法也叫作"上下文管理 ...
- python3.6以上 asyncio模块的异步编程模型 async await语法
这是python3.6以上版本的用法,本例是python3.7.2编写使用asyncio模块的异步编程模型,生产这消费者,异步生产,用sleep来代替IO等待使用async和await语法来进行描述a ...
- 《浏览器工作原理与实践》<09>块级作用域:var缺陷以及为什么要引入let和const?
在前面我们已经讲解了 JavaScript 中变量提升的相关内容,正是由于 JavaScript 存在变量提升这种特性,从而导致了很多与直觉不符的代码,这也是 JavaScript 的一个重要设计缺陷 ...
- 大数据学习(09)—— Hive语法
Hive官方网站上有详细的语法说明,参考LanguageManual. 这里我把最常用的几块列出来. HIVE DDL Database 建库语句 CREATE (DATABASE|SCHEMA) [ ...
- Linux - 简明Shell编程09 - 重定向(Redirection)
脚本地址 https://github.com/anliven/L-Shell/tree/master/Shell-Basics 示例脚本及注释 #!/bin/bash pwd > 1.log ...
- 编程类-----matlab基础语法复习(1)
2019年美赛随笔记录: 具体功能:基础语法+基本运算+画图+矩阵+excel读取....... 所遇问题及其解决方案: 1. que:matlab中plot画图无法复制下来图片? ...
- Spark入门到精通--(第二节)Scala编程详解基础语法
Scala是什么? Scala是以实现scaleable language为初衷设计出来的一门语言.官方中,称它是object-oriented language和functional languag ...
- 【shell编程】2、语法
Linux 下执行.sh文件总是提示permission denied 如果你是root登陆的话(不是的话,切换到root用户,对*.sh赋可执行的权限) chmod 777 *.sh or ...
随机推荐
- 剑指Offer——简述堆和栈的区别
剑指Offer--简述堆和栈的区别 堆(Heap) Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建: Java虚拟机规范描述:所有的对象实例及数组都要在堆上分配: Java堆可以处于物理 ...
- 【移动开发】plurals
不同的语言对数量的语法规定有不同的规则.在英语里面,例如,1是特例.我们会直接写1book,而针对一个以上的我们会在book后加复数形式.这种区别对单数和复数来说是很普遍的,但是其他的语言做了更好的区 ...
- Editorial Board 、co-editor、ediitor、editor-in-chief的区别
昨天更新掘金APP-IOS之后发现一个比较严重的Bug,联系管理者报告了Bug,中途发现掘金的发布功能需要申请成为co-editor才行. 那么这里科普一下这几个名词: Editorial Board ...
- iOS中 为 iOS 建立 Travis CI 韩俊强的博客
每日更新关注:http://weibo.com/hanjunqiang 新浪微博! 你是否曾经试着为 iOS 项目搭建一台支持持续集成的服务器,从我的个人经验而言,这可不是一个轻松的活.首先需要准备 ...
- JAVA之旅(二十五)——文件复制,字符流的缓冲区,BufferedWriter,BufferedReader,通过缓冲区复制文件,readLine工作原理,自定义readLine
JAVA之旅(二十五)--文件复制,字符流的缓冲区,BufferedWriter,BufferedReader,通过缓冲区复制文件,readLine工作原理,自定义readLine 我们继续IO上个篇 ...
- BLOCK/字面量(语法糖)OC——第六天
1.//block ,块语法,实质是匿名函数,是对C语言中函数的扩充,扩展: //block 语法可以用来保存一段代码或者用来调用一段封装好的代码: //block 语法由于是C语言实现的,所以执 ...
- (NO.00001)iOS游戏SpeedBoy Lite成形记(十九)
最后就是要完成前面设定的第3件事:如果玩家赌对了则赢钱,反之输钱. 前面的框架搭的差不多了,所以这里实现起来也就不难了 ;) 首先我们怎么知道用户输入完毕,然后关闭窗口了?只有在这个点上GameSce ...
- Leetcode_104_Maximum Depth of Binary Tree
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41964475 Maximum Depth of Binar ...
- 彻底搞清楚 RxJava 是什么东西
其实从rxjava14年出现到现在,我是去年从一个朋友那里听到的,特别是随着现在app项目越来越大,分层越来越不明确的情况下,rxjava出现了,以至于出现了rxandroid.其实如果你了解观察者模 ...
- 《java入门第一季》之面向对象面试题(fianl关键字)
/* 面试题:final修饰局部变量的问题 基本类型:基本类型的值不能发生改变. 引用类型:引用类型的(地址值)(不能发生改变),但是,该对象的堆内存的值是可以改变的. */ class Studen ...