Objective-C块,递归失败 [英] Objective-C Blocks, Recursion Fails

查看:151
本文介绍了Objective-C块,递归失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一个函数来调用自己,但把一切都放在一个块中,

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆