Objective-C块中的代码如何引用块对象本身?

Ste*_*ler 17 objective-c objective-c-blocks

self 块仅仅是一个块内的捕获变量,并且不引用块本身,那么块如何在没有为此目的的显式捕获变量的情况下引用自身?

bbu*_*bum 16

__block void(^strawberryFields)();
strawberryFields = [^{ strawberryFields(); } copy];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),
               strawberryFields);
Run Code Online (Sandbox Code Playgroud)
  • 你使用的是__block因为该块将复制strawberryFields创建块的值,该块将在赋值之前.

  • 您还必须copy在任何其他复制操作之前执行该块,否则您最终会得到一个引用堆栈原始版本的块.

  • 请注意,上面的代码泄漏了块.在某个地方,需要有一个release块来平衡副本.


adi*_*dib 5

我发现这种模式在ARC(自动引用计数)中工作和稳定,在Debug和Release版本中都是如此.

-(void) someMethod
{
    // declare a __block variable to use inside the block itself for its recursive phase.
    void __block (^myBlock_recurse)();

    // define the block
    void (^myBlock)() = ^{
        // ... do stuff ...
        myBlock_recurse(); // looks like calling another block, but not really.
    };

    // kickstart the block
    myBlock_recurse = myBlock; // initialize the alias
    myBlock(); // starts the block
}
Run Code Online (Sandbox Code Playgroud)

最初我尝试将一个__block修饰符myBlock直接放入并使用该变量直接在块的实现中进行递归.这适用于ARC Debug构建,但EXC_BAD_ACCESS在Release构建中断开.另一方面,删除__block修饰符会引发"当被块捕获时未定义的变量"警告(我不愿意运行它并进行测试).

  • 在ARC中,这会导致保留周期 (3认同)

MHC*_*MHC 0

我以前从未尝试过此操作,并且不能 100% 确定它是否有用(如果有效),但例如:

typedef void (^BasicBlock)(void);

__block BasicBlock testBlock;
testBlock  = ^{NSLog(@"Testing %p", &testBlock);};
testBlock();
Run Code Online (Sandbox Code Playgroud)

您可能已使用 __block 声明变量以防止自保留循环。