A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© wslinke 中级黑马   /  2015-4-18 17:54  /  1868 人查看  /  11 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 wslinke 于 2015-4-18 17:59 编辑

今天在学习block的时候有诸多疑惑,就硬着头皮翻看了苹果官方文档中block的有关部分
我翻译了一部分出来和大家分享一下
鉴于英语水平和专业水准有限,可能存在一些错误,欢迎大家指正

Working with Blocks
An Objective-C class defines an object that combines data with related behavior.
(Block是)一个OC类定义的,结合了数据与相关行为的对象。
Sometimes, it makes sense just to represent a single task or unit of behavior, rather than a collection of methods.
有时,在表示单个任务或单元的行为时,比起方法的集合,Block会更加适合.
Blocks are a language-level feature added to C, Objective-C and C++, which allow you to create distinct segments of code that can be passed around to methods or functions as if they were values.
Blocks作为语言级别的特征被添加到C,OC和C++中,它允许你创建不同的,可以被传递到方法和函数中的的代码片段,就像是数值一样.
Blocks are Objective-C objects, which means they can be added to collections like NSArray or NSDictionary. They also have the ability to capture values from the enclosing scope, making them similar to closures or lambdas in other programming languages.
Blocks是OC对象,这意味着它可以被加入OC集合中,比如NSArray、NSDictionary,它还有从封闭范围中获取值的能力,这类似于其他程序设计语言中的closures或lambdas.
This chapter explains the syntax to declare and refer to blocks, and shows how to use blocks to simplify common tasks such as collection enumeration. For further information, see Blocks Programming Topics .
这章解释了blocks的声明和引用,还展示了怎样使用blocks去简化一些常见的任务,比如列举集合中的元素.
Block Syntax
The syntax to define a block literal uses the caret symbol (^), like this:
定义一个Block的语法是使用插入符号^,就像这样
  1. ^{
  2.         NSLog(@”This is a block”);
  3. }
复制代码


As with function and method definitions, the braces indicate the start and end of the block. In this example, the block doesn’t return any value, and doesn’t take any arguments.
正如函数和方法的定义一样,花括号指示了block的开始和结束.在这个例子中,block没有返回任何值,也没有接受任何参数.
In the same way that you can use a function pointer to refer to a C function, you can declare a variable to keep track of a block, like this:
就像可以使用一个函数指针去引用C函数一样,你也可以声明一个变量去保存block的踪迹,就如下面一样:
   
  1.    void (^simpleBlock)(void);
复制代码


If you’re not used to dealing with C function pointers, the syntax may seem a little unusual.
如果你不习惯于使用C函数指针,这种语法可能会让你感觉不太寻常.
This example declares a variable called simpleBlock to refer to a block that takes no arguments and doesn’t return a value, which means the variable can be assigned the block literal shown above, like this:
这个例子声明了一个名为变量simpleBlock的变量,来引用一个不接受任何参数也不返回任何值的block,这意味着可以将上面的那个block赋给这个变量,就像这样:
  1. simpleBlock = ^{
  2.         NSLog(@”This is a block”);
  3. };
复制代码



This is just like any other variable assignment, so the statement must be terminated by a semi-colon after the closing brace.
就像是其他变量赋值一样,这个声明必须在括号后面加上分号来结束;
You can also combine the variable declaration and assignment:
你也可以同时对在声明这个变量的同时对它赋值,就像这样:
  1. void (^simpleBlock)(void) = ^{
  2.     NSLog(@"This is a block");
  3. };
复制代码


Once you’ve declared and assigned a block variable, you can use it to invoke the block:
当你已经对一个block变量进行声明和赋值,你就可以使用下面这种方式来调用这个block
simpleBlock();

Note: If you attempt to invoke a block using an unassigned variable (a nil block variable ),your app will crash.
注意,如果你试图调用一个没有赋值的变量(一个空的block变量),你的程序会奔溃.
Blocks Take Arguments and Return Values
Blocks can also take arguments and return values just like methods and functions.
就像方法和函数一样,Blocks同样可以接受参数和返回值.
As an example, consider a variable to refer to a block that returns the result of multiplying two values:
下面是一个例子,声明了一个变量来引用返回2个数乘积的block
  1. double (^multiplyTwoValues)(double, double);
复制代码



The corresponding block literal might look like this:
与之匹配的block可能是这样的:

  1. ^ (double firstValue, double secondValue) {
  2.     return firstValue * secondValue;
  3. }
复制代码


The firstValue and secondValue are used to refer to the values supplied when the block is invoked, just like any function definition. In this example, the return type is inferred from the return statement inside the block.
firstValue 和 secondValue是用来引用这个block被调用时传入的参数,就像函数定义那样.在这个例子中,返回值的类型是根据block中的返回语句推断的.
If you prefer, you can make the return type explicit by specifying it between the caret and the argument list:
如果你愿意,你可以在插入符号^和参数列表之间指定返回值的类型
  1. ^ double (double firstValue, double secondValue) {
  2.     return firstValue * secondValue;
  3. }
复制代码


Once you’ve declared and defined the block, you can invoke it just like you would a function:
一旦你已经声明和定义了block,你就可以想调用函数一样来调用它.

  1. double (^multiplyTwoValues)(double, double) =
  2.                           ^(double firstValue, double secondValue) {
  3.                               return firstValue * secondValue;
  4.                           };
  5. double result = multiplyTwoValues(2,4);
  6. NSLog(@"The result is %f", result);
复制代码


11 个回复

倒序浏览
干得好,你的英语是几级啊?
回复 使用道具 举报
15098037606 发表于 2015-4-18 18:27
干得好,你的英语是几级啊?

四级啊 翻译这个我必须要用字典的
回复 使用道具 举报

Blocks Can Capture Values from the Enclosing Scope
As well as containing executable code, a block also has the ability to capture state from its enclosing scope.
就像包含可执行代码一样,block同样有能力从封闭范围内获取状态
If you declare a block literal from within a method, for example, it’s possible to capture any of the values accessible within the scope of that method, like this:
例如,如果你在一个方法内声明了一个block, 它将可以获取在这个方法范围内任何可以访问的值,就像这样

  1. - (void)testMethod {
  2.     int anInteger = 42;
  3.     void (^testBlock)(void) = ^{
  4.         NSLog(@"Integer is: %i", anInteger);
  5. };
  6.     testBlock();
  7. }
复制代码


In this example, anInteger is declared outside of the block, but the value is captured when the block is defined.
在这个例子中,anInteger被定义在了block的外面,但在block被定义时,它的值被获取到了
Only the value is captured, unless you specify otherwise. This means that if you change the external value of the variable between the time you define the block and the time it’s invoked, like this:



只有值被获取到了,除非你额外指定(否则值是不会改变的).这意味着如果你在调用block之前,且在声明这个block之后改变了一个外部变量(这个变量的值是不会被重新赋给block的),像这样:

  1. int anInteger = 42;
  2. void (^testBlock)(void) = ^{
  3.     NSLog(@"Integer is: %i", anInteger);
  4. };
  5. anInteger = 84;
  6. testBlock();
复制代码



the value captured by the block is unaffected. This means that the log output would still show:
block所获取的值并没有被影响到,这意味着输出仍然会是:
  1. Integer is: 42
复制代码


It also means that the block cannot change the value of the original variable, or even the captured value (it’s captured as a const variable).
这同样意味着block不能改变源变量的值,甚至不能改变获取到的值(它将被获取视为一个const变量)
Use __block Variables to Share Storage
If you need to be able to change the value of a captured variable from within a block, you can use the __block storage type modifier on the original variable declaration.
如果你想要在block里改变一个获取到的变量的值,你可以在源变量声明时使用__block这种存储类型修饰符来修饰它.
This means that the variable lives in storage that is shared between the lexical scope of the original variable and any blocks declared within that scope.
这意味着该变量可以在任意一个处于该变量作用域的block中共享数据
As an example, you might rewrite the previous example like this:
例如,你可以像这样重写上面那个例子:
  1. Integer is: 42
  2. __block int anInteger = 42;
  3. void (^testBlock)(void) = ^{
  4.     NSLog(@"Integer is: %i", anInteger);
  5. };
  6. anInteger = 84;
  7. testBlock();
复制代码


Because anInteger is declared as a __block variable, its storage is shared with the block declaration. This means that the log output would now show:
由于anInteger 被声明为__block变量,它将被存储为与block声明共享的变量,这意味着输出将会变为:
  1. Integer is: 84
复制代码


It also means that the block can modify the original value, like this:
这同样意味着block可以修改原始数值,像这样:
  1. __block int anInteger = 42;
  2. void (^testBlock)(void) = ^{
  3.     NSLog(@"Integer is: %i", anInteger);
  4.     anInteger = 100;
  5. };
  6. testBlock();
  7. NSLog(@"Value of original variable is now: %i", anInteger);
  8. This time, the output would show:
复制代码


这次,输出将会是:
  1. Integer is: 42
  2. Value of original variable is now: 100
复制代码


回复 使用道具 举报
很给力啊,英语学得不错
回复 使用道具 举报
还好,生词不是很多,不过翻译得很好
回复 使用道具 举报
MadRoy 初级黑马 2015-12-22 12:06:16
7#
拿走复习用
回复 使用道具 举报
qu29437 来自手机 中级黑马 2015-12-22 12:24:01
8#
加油好好学习天天向上
回复 使用道具 举报
chensc 金牌黑马 2015-12-22 20:57:15
9#
学习学习!
回复 使用道具 举报
让人蛋疼的东西啊
回复 使用道具 举报
赞赞顶一个。。
回复 使用道具 举报
马上就要学到了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马