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”在块捕获时未初始化
)。
有几种方法可以解决这个问题,但最明显和最简单的方法就是使块本身成为__block
variables(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();