11

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

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.

    }

    // ...

  }

我不知道我应该避免什么模式。似乎我可以调用与块定义具有相同文字范围的块,例如在“if”或“for”语句后面。你能帮我解释一下吗?

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

4

2 回答 2

9

我认为指针的类比如下。

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

通常,块文字本身只存在于它定义的块中,因此当离开该块时,文字会消失(就像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.
于 2012-11-28T00:07:20.960 回答
0

I was reading apple's documentation on blocks and did a little more research on this part. It looks to me with ARC the second example code is totally fine. I didn't try the first example. The general idea in the accepted answer is correct. However, with ARC, when you assign the literal block (NSStackBlock) to a local variable, the block is copied to heap, and if you inspect the block, you'll see it's indeed a NSMallocBlock. I also referenced this blog on this topic https://www.cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html

于 2017-01-24T03:17:49.807 回答