Objective-C块,递归失败 [英] Objective-C Blocks, Recursion Fails
问题描述
我试图做一个函数来调用自己,但把一切都放在一个块中,
I'm trying to do a function that calls itself but by putting everything on one block,
正如你所看到的,下面的函数被称为不确定的次数(直到arcrandom返回一个小于50的数字),你应该期望输出一个变量号的RUNNING消息,取决于的机会。
As you can see, the following function is intended to be called an indefinite amount of times (until arcrandom returns a number lower than 50) and you should expect as an output a variable number of "RUNNING" messages, depending on chance.
void (^_test_closure)(void) = ^ {
NSLog(@"RUNNING");
if(arc4random() % 100 > 50) {
_test_closure();
}
};
_test_closure();
但是,当运行它,我得到一个EXC_BAD_ACCESS错误,我发现的原因是,代码试图在闭包中调用_test_closure它基本上指向无处。
However, when running it, I get an EXC_BAD_ACCESS error and the reason I've found is that when the code tries to calls _test_closure inside of the closure it basically points to nowhere.
有没有人知道如何使上述代码工作?
Does anyone know how to make the above code work?
推荐答案
递归和块是棘手的。因为一个块捕获所有传入的变量,变量 _test_closure
还没有初始化(和clang应该给你一个警告:
Recursion and blocks is tricky. Because a block captures all variables passed in, the variable _test_closure
is not initialized yet (and clang should give you a warning:
阻止指针变量'_test_closure'在被块
Block pointer variable '_test_closure' is uninitialized when captured by block
捕获时未初始化。
有几种方法可以解决这个问题,但最明显的&最简单的就是使块本身成为一个 __ block
变量(什么@ H2CO3说)。这允许块 weak-linked
几乎,所以当你再次调用它,它被正确初始化。
There are several ways you can get around this, but the most obvious & simplest is to just make the block itself a __block
variable (what @H2CO3 said). This allows the block to be weak-linked
almost, so that when you call it again, it is properly initialized.
另一个选项是使块成为全局或静态,如下所示:
Another option you have is making the block a global or static, like this:
// 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);
}
}
这意味着它不会被块捕获,而是引用全局/静态变量,所有代码可以平等地更改。
This means it's not being captured by the block, but instead it's referencing the global / static variable, which can be changed by all code equally.
这篇关于Objective-C块,递归失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!