我不知道对于objective-c中的字面范围我应该避免哪些模块

jer*_*lei 11 block objective-c ios

在Apple的文档中说:块文字(即^ {...})是表示块的堆栈本地数据结构的地址.因此,堆栈本地数据结构的范围是封闭的复合语句,因此您应该避免以下示例中显示的模式:

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.
    }

    //for example I invoke the block here
    blockArray[1]();
  }


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.

    }

    // ...

  }
Run Code Online (Sandbox Code Playgroud)

我不知道应该避免哪些模式.看起来我可以调用与块定义具有相同文字范围的块,例如在"if"或"for"语句后面.你能帮我解释一下吗?

这是链接https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Blocks/Articles/bxUsing.html#//apple_ref/doc/uid/TP40007502-CH5-SW1

use*_*136 9

我认为对指针的类比如下.

void foo() {
  int *block = NULL;
  {
    int a;
    block = &a;
  }
  // `block`, even though defined here, points to
  // an invalid memory address.
}
Run Code Online (Sandbox Code Playgroud)

通常,块文字本身仅存在于其定义的块中,因此当离开该块时,文字消失(就像a上面示例中的变量一样),并且您留下了悬空指针.

因此,通常会将块复制到堆中以供将来使用.非ARC代码使用block_copy和朋友.复制到堆中还会捕获块使用的所有相关变量(可能会创建保留周期).

在实践中,所有这些都被ARC,属性和类的使用所避免.您copy在类中定义属性,然后只为其分配块.如果让编译器生成getter/setter,则块文本将自动复制到堆中.

@interface Bla : NSObject
@property (nonatomic, copy) void (^blockProperty)(int i);
@endf

...

Bla *bla = [[Bla alloc] init];
{
  bla.blockProperty = ^(int i) { printf("%d", i); };
}
// bla.blockProperty now points to a heap copy of the block literal from above,
// so it's not dangling.
Run Code Online (Sandbox Code Playgroud)