Brief Intro to Blocks 3: Blocks Are Closures
来源:互联网 发布:koala for mac 下载 编辑:程序博客网 时间:2024/05/10 11:22
Blocks Are Closures!
As stated earlier in this chapter, a block is an implementation of a closure, a function that allows access to local variables declared outside of its typical scope. To understand what this means, let’s take a moment to understand scope and visibility rules. The visibility of a variable refers to the portion(s) of a program in which it can be accessed; this is also referred to as a variable’s scope. For example, variables declared within a C function definition have local scope, meaning that they are visible and accessible within the function, and not accessible elsewhere. (Note that a function can also reference global variables.) A block augments the visibility of variables compared to C functions through several features, as follows:
- Support for lexical scope. This is the ability to reference local variables and parameters from an enclosing scope.
- __block variables. The __block keyword, applied to a variable outside a block but within the same lexical scope, enables this variable to be modified within a block.
- Instance variable access. A block defined within an object’s method implementationcan access the object’s instance variables.
- const imports. Constant variables imported through a header file (via an #import or#include directive) are visible within a block literal expression.
Lexical Scope
One of the unique features of blocks is its support for lexical scoping. In contrast, C functions do not have access to local variables declared outside of their definition. The example shown in Listing 15-9will not compile because the local variable myVar is not visible within the logValue function definition.
Listing 15-9. C Function Attempting to Access a Local Variable Outside Its Scope
void logValue(){ // ERROR, illegal access of myVar, not within scope NSLog(@"Variable value = %d", myVar);}int main(int argc, const char * argv[]){ @autoreleasepool { int myVar = 10; logValue(); } return 0;}
A block supports lexical scoping, thus a block literal expression has access to variables declared within the same lexical scope. In addition, blocks can be defined anywhere other variables can; for example, within other blocks, functions, and methods. C functions, on the other hand, cannot be defined within other functions or methods. Listing 15-10 compiles and runs successfully because the variable myVar is declared within the same lexical scope as the block logValueBlock.
Listing 15-10. Block Accessing Local Variable Through Lexical Scoping
{ int myVar = 10; void (^logValueBlock)(void) = ^{ NSLog(@"Variable value = %d", myVar); }; logValueBlock();}
Listing 15-10 shows that a block has access to local variables declared outside its definition. Specifically, these local variables are declared (and initialized) within an enclosing scope, prior to the block literal expression. Braces delimit a local scope; in addition scopes may be nested. Referring again to Listing 15-10, the variable myVar is declared at the same scope as the block definition assigned to logValueBlock, prior to the literal expression, and thus can be used within the expression. On the other hand, Listing 15-11 will not compile, because the local variable myVar is declared and initialized after the block literal expression.
Listing 15-11. Illegal Access of Local Variable in Block, Declared After Block Literal Expression
void (^logValueBlock)(void) = ^{ // ERROR, illegal access of myVar, declared after literal expression NSLog(@"Variable value = %d", myVar);};int myVar = 10;logValueBlock();
Local variables accessed through lexical scoping behave as constant values (for primitive types) or by reference variables (for objects) within a block literal expression. Listing 15-12 will not compile because a primitive variable accessed through lexical scoping cannot be modified within a block literal.
Listing 15-12. Block Attempting to Modify a Local Variable Accessed Through Lexical Scoping
int myVar = 10;void (^logValueBlock)(void) = ^{ // ERROR, lexical scope variable not assignable myVar = 5; NSLog(@"Variable value = %d", myVar);};logValueBlock();
As local scopes can be nested, a block can capture local variables within multiple (nested) scopes. This is demonstrated in the code from Listing 15-13.
Listing 15-13. Block Capturing Local Variables Within Multiple Nested Scopes
for (int ii=0; ii<2; ii++){ for (int jj=0; jj<3; jj++) { void (^logValueBlock)(void) = ^{ NSLog(@"Variable values = %d, %d", ii, jj); }; logValueBlock(); }}
Mutable __block Variables
By default, block local variables accessed through lexical scoping are visible but not writeable within a block literal expression. The __block storage type modifier can be used to make these variables read-write (i.e., mutable). The __block modifier can be used on all supported Objective-C types, except for C variable-length arrays (an array with a length that is not a constant expression) and C structures that contain variable-length arrays. Its use cannot be combined with the existing local storage modifiers auto, register, and static. Listing 15-14 illustrates the use of a __blockvariable.
Listing 15-14. Correct Use of __block Storage
__block int myVar = 10;void (^incBlock)(int) = ^(int amount){ myVar += amount; NSLog(@"New value = %d", myVar);};incBlock(5);
Variables qualified with the __block storage type are copied to the heap if the referencing block is copied to heap storage. This last point brings up the topic of memory management with blocks, the subject of the next section.
- Brief Intro to Blocks 3: Blocks Are Closures
- Brief Intro to Blocks 5:Using Blocks
- Brief Intro to Blocks 1:Definition
- Brief Intro to Blocks 2:Block Syntax
- Brief Intro to Blocks 4:Memory Management with Blocks
- Ruby Blocks & Closures
- blocks
- Blocks
- Blocks
- Blocks
- Blocks
- Blocks
- Blocks
- Blocks
- Brief Intro to Foundation Functions
- Brief Intro to Expression Literals
- Are @autoreleasepool Blocks More Efficient?
- IOS Dev Intro - Blocks Programming Series 06
- 计算机发展简史
- Java中final 与C++中Const的区别
- 关于"保留小数点后几位数字“
- unresolved external symbol "protected: virtual struct AFX_MSGMAP const * __thiscall
- 系统分析员、架构师、项目经理”之间有着什么样的差别
- Brief Intro to Blocks 3: Blocks Are Closures
- python中的map、filter、reduce函数
- hdu 2102 A计划 我用的是dfs
- 解析JVM线程同步机制
- 关于keil MDK 的配置文件Configuration Wizard
- Android,UI主线程与子线程
- Swing中弹出对话框的几种方式_JOptionPane.showMessageDialog等详解
- 卷积神经网络CNN
- restlet中如何获取post方式提交的表单值