在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:块的语法的更多相关文章

  1. 【Shell编程】Shell基本语法

    Shell 语法   Shell程序设计作为一种脚本语言,在Linux系统中有广泛的应用,本文记录了关于Shell程序设计的基础语法知识和常用命令,方便查询,熟练使用shell也需要经常实践,这对于完 ...

  2. Python并行编程(八):with语法

    1.基本概念 当有两个相关的操作需要在一部分代码块前后分别执行的时候,可以使用with语法自动完成.同时,使用with语法可以在特定的地方分配和释放资源,因此,with语法也叫作"上下文管理 ...

  3. python3.6以上 asyncio模块的异步编程模型 async await语法

    这是python3.6以上版本的用法,本例是python3.7.2编写使用asyncio模块的异步编程模型,生产这消费者,异步生产,用sleep来代替IO等待使用async和await语法来进行描述a ...

  4. 《浏览器工作原理与实践》<09>块级作用域:var缺陷以及为什么要引入let和const?

    在前面我们已经讲解了 JavaScript 中变量提升的相关内容,正是由于 JavaScript 存在变量提升这种特性,从而导致了很多与直觉不符的代码,这也是 JavaScript 的一个重要设计缺陷 ...

  5. 大数据学习(09)—— Hive语法

    Hive官方网站上有详细的语法说明,参考LanguageManual. 这里我把最常用的几块列出来. HIVE DDL Database 建库语句 CREATE (DATABASE|SCHEMA) [ ...

  6. Linux - 简明Shell编程09 - 重定向(Redirection)

    脚本地址 https://github.com/anliven/L-Shell/tree/master/Shell-Basics 示例脚本及注释 #!/bin/bash pwd > 1.log ...

  7. 编程类-----matlab基础语法复习(1)

    2019年美赛随笔记录: 具体功能:基础语法+基本运算+画图+矩阵+excel读取....... 所遇问题及其解决方案:         1.   que:matlab中plot画图无法复制下来图片? ...

  8. Spark入门到精通--(第二节)Scala编程详解基础语法

    Scala是什么? Scala是以实现scaleable language为初衷设计出来的一门语言.官方中,称它是object-oriented language和functional languag ...

  9. 【shell编程】2、语法

    Linux 下执行.sh文件总是提示permission denied 如果你是root登陆的话(不是的话,切换到root用户,对*.sh赋可执行的权限) chmod 777 *.sh   or    ...

随机推荐

  1. Github上怎么修改别人的项目并且提交给原作者!图文并茂!

    Github上怎么修改别人的项目并且提交给原作者!图文并茂! 写这篇博客的初衷,是因为我的项目Only需要一些朋友一起参与进来,但是很多的Git都不是很熟练,其实版本控制这种东西没有什么难度的,只要稍 ...

  2. acm入门搜索-水池数目

    水池数目 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池,假设有一张我们学校的某处的地图,这个地图上仅标识了此处 ...

  3. Activity绑定自定义视图

    在安卓工程中,我们通过创建可以自动生成on_Create方法,这里面有个: setContentView(R.layout.activity_main);是系统自带的一个布局文件,但是在开发的过程中, ...

  4. Caffe框架,训练model并测试数据

    1. 训练model #!/usr/bin/env sh ./build/tools/caffe train --solver=examples/focal_length/focal_solver.p ...

  5. 11.2、Libgdx的音频之音乐

    (官网:www.libgdx.cn) 对于任何超过5秒的声音来说,最好将其放到磁盘中而不是内存中.Libgdx提供了一个Music接口来帮我们实现. 以下载入Music实例: Music music ...

  6. Python+Visual Studio

    一直在找一个比较好的Python IDE,无奈找来找去都不太好用,由于经常用Visual Studio,所以很希望找到一个能够在VS中的Python扩展.今天发现了一个很给力的VS扩展,可以在VS中方 ...

  7. 理解WebKit和Chromium: Android 4.4 上的Chromium WebView

    转载请注明原文地址:http://blog.csdn.net/milado_nju ## 概述 相信读者已经注意到了,在最新的Android 4.4 Kitkat版本中,原本基于Android Web ...

  8. spring与mybatis(oracle)整合

    今天闲着无聊把项目拆解开,抽出了spring与mybatis部分.做了个demo,希望对初学者有些帮助,另外整个demo是从项目中完整剥离下来的,里面的架构大家也可以参考一下. 先是完整的项目图 首先 ...

  9. 用 boost::multi_index 管理玩家

    用 boost::multi_index 管理玩家(金庆的专栏)网游服务器上的玩家集合需要多种索引:如用ID查找,角色名查找, 用登录时分配的会话ID查找.用boost::multi_index进行玩 ...

  10. Html.java 存储页面信息类

    Html.java 存储页面信息类 package com.iteye.injavawetrust.miner; /** * 存储页面信息类 * @author InJavaWeTrust * */ ...