block学习

来源:互联网 发布:php众筹源码 编辑:程序博客网 时间:2024/06/05 09:07

block

1.是匿名函数,(anonymous function),没有名字的函数,意义??

2.基本格式


2.block可以做为变量,直接传递,不需要声明,如:


其中,最后一个是一个block的变量


3. block functionality:有 参数、返回值、可以使用或修改作域内变量等,与其他blockshare、在其他作用域销毁后与其他block继续share/modify state等,原文:

A block is an anonymous inline collection of code that:

Has a typed argument list just like a function

Has an inferred or declared return type

Can capture state from the lexical scope within which it is defined

Can optionally modify the state of the lexical scope

Can share the potential for modification with other blocks defined within the same lexical scope

Can continue to share and modify state defined within the lexical scope (the stack frame) after the lexical scope (the stack frame) has been destroyed


4.Usage :(主要用与回调)

concurrently, or over items in a collection, or as a callback when another operation has finished.


用作回调的原因:写在函数后面作为参数,可以使用局部变量:

Blocks are a useful alternative to traditional callback functions for two main reasons:

  1. They allow you to write code at the point of invocation that is executed later in the context of the method implementation.
    Blocks are thus often parameters of framework methods. 
  2. They allow access to local variables.
    Rather than using callbacks requiring a data structure that embodies all the contextual information you need to perform an operation, you simply access local variables directly. 


5.Declaring and Creating Blocks

5.1 声明形式类似指针,只是把 * 用 ^ 替换

5.2 

5.2 .1.全局变量可读取

5.2 .2.参数可读取

5.2 .3.非静态局部变量作为const,只能读不能改变

5.2 4.局部__block变量可mutable

The following rules apply to variables used within a block:

  1. Global variables are accessible, including static variables that exist within the enclosing lexical scope. 
  2. Parameters passed to the block are accessible (just like parameters to a function). 
  3. Stack (non-static) variables local to the enclosing lexical scope are captured asconstvariables.
    Their values are taken at the point of the block expression within the program. In nested blocks, the value is captured from the nearest enclosing scope. 
  4. Variables local to the enclosing lexical scope declared with the __block storage modifier are provided by reference and so are mutable.
    Any changes are reflected in the enclosing lexical scope, including any other blocks defined within the same enclosing lexical scope. These are discussed in more detail in“The __block Storage Type”(page 15). 

5. Local variables declared within the lexical scope of the block, which behave exactly like local variables in a function.

Each invocation of the block provides a new copy of that variable. These variables can in turn be used asconstor by-reference variables in blocks enclosed within theblock.


6.__block 变量

全局动态变量,全局静态变量,局部变量,__block局部变量区别:(只有局部变量不能被block修改)

extern NSInteger CounterGlobal;static NSInteger CounterStatic;  {      NSInteger localCounter = 42;      __block char localCharacter;      void (^aBlock)(void) = ^(void) {          ++CounterGlobal;          ++CounterStatic;CounterGlobal = localCounter; // localCounter fixed at block creation          localCharacter = 'a'; // sets localCharacter in enclosing scope      };      ++localCounter; // unseen by the block      localCharacter = 'b';      aBlock(); // execute the block      // localCharacter now 'a'  }


7.object and block variables 这章不太懂


8. BOOL *stop 意思??


9.blocks拷贝,仅仅当希望当作用域销毁后,仍能使用block的时候:

Block_copy();

Block_release();


10.避免使用的情况:

A block literal (that is, ^{ ... }) is the address of astack-localdata structure that represents the block. The scope of the stack-local data structure is therefore the enclosing compound statement, so you shouldavoidthe patterns shown in the following examples:

 void dontDoThis() {      void (^blockArray[3])(void);  // an array of 3 block references      for (int i = 0; i < 3; ++i) {blockArray[i] = ^{ printf("hello, %d\n", i); };          // WRONG: The block literal scope is the "for" loop.      }} void dontDoThisEither() {      void (^block)(void);      int i = random():      if (i > 1000) {          block = ^{ printf("got i at: %d\n", i); };          // WRONG: The block literal scope is the "then" clause.      }// ... }


对以上代码进行测试:

void dontDoThis() {    void (^blockArray[3])(void); // an array of 3 block references    for (int i = 0; i < 3; ++i) {        blockArray[i] = ^{printf("hellp,%d\n",i);};        // WRONG: The block literal scope is the "for" loop.    }        blockArray[0]();blockArray[1]();blockArray[2]();}

注:这段代码,发现可以打印出值,但是都是打印的 blockArray[2]()的值,观察内存地址,发现三个的内存地址都一样

void dontDoThisEither() {    void (^block)(void);    int i = 10000;    if (i > 1000) {        block = ^{ printf("got i at: %d\n", i); };        // WRONG: The block literal scope is the "then" clause.    }    block();}

注:这段代码,发现可以正常打印值,不知道文档上说的是什么意思


11.Debugging

GDB下,可以用 invoke-block,调试,如:

$ invoke-block myBlock 10 20


注;在LLVM的话,该指令无效


blog内容:

该代码中,后面修改了make的值,但是在block内部,make的值仍是 Honda,因为block开始把make的值作为const拷贝到block内,就冻结并一直使用该值


小结,个人理解:

1.block 目前主要作为回调使用

2.block 的基本 格式 void (^block)(int )=^(int x){return x;};

3.block可以修改全局变量,静态变量,__block变量,但不能修改局部非静态变量(这种情况是把变量作为const拷贝一份到block内)


其他资料:

1.官方文档:

2.blog:

初始block

深度围观block:第一集

深度围观block:第二集

深度围观block:第三集

Block剧终:Objective-C中的闭包性和匿名函数