Objective-C块,recursion失败

Sup家伙,

我试图做一个自我调用的function,但把所有的东西放在一个块上,

正如你所看到的,下面的函数被称为无限次(直到arcrandom返回一个低于50的数),你应该期望输出一个可变数量的“RUNNING”消息,这取决于机会。

void (^_test_closure)(void) = ^ { NSLog(@"RUNNING"); if(arc4random() % 100 > 50) { _test_closure(); } }; _test_closure(); 

但是,运行它时,我得到一个EXC_BAD_ACCESS错误,我发现的原因是当代码尝试调用闭包内的_test_closure时,它基本上指向无处。

有谁知道如何使上面的代码工作?

recursion和块是棘手的。 因为一个块捕获所有传入的variables,variables_test_closure还没有被初始化(和_test_closure应该给你一个警告:

块指针variables“_test_closure”在块捕获时未初始化

)。

有几种方法可以解决这个问题,但最明显和最简单的方法就是使块本身成为__blockvariables(H2CO3所说的)。 这使得块几乎是weak-linked ,所以当你再次调用它时,它会被正确地初始化。

你拥有的另一个选项是使块成为全局或静态的,如下所示:

 // outside of 'main', thus being a global variable void (^blockRecurse)(int) = ^(int level) { if (level < 0) return; NSLog(@"Level: %i", level); blockRecurse(--level); }; int main() { @autoreleasepool { blockRecurse(10); } } 

这意味着它不被块捕获,而是引用全局/静态variables,这可以被所有代码均等地改变。

您必须将块本身声明为块variables:

 __block void (^_test_closure)(); _test_closure = ^{ NSLog(@"Running..."); if ((arc4random() % 100) > 50) { _test_closure(); } } _test_closure(); 

它适用于XCode 5 – 没有警告,没有保留周期:

 typedef void(^blockT)(); blockT block1; blockT __block block1recursive; block1recursive = block1 = ^(){ block1recursive(); }; block1();