Objective c — 更新块中的参数

Objective c — Update parameter in block

我正在对树遍历进行一些修补(我已经以更直接的方式解决了这个问题)但是我在以下 Objective C 逻辑中遇到了一个问题:

- (NSString *)someWrapperFunction
{
    NSString *result = @"";

    NSString *(^appendBlock)(int, NSString **) = ^NSString *(int a, NSString **adder){
        if (a == 0)
        {
            // base case
            return @"";
        }

        NSLog(@"%d", a);

        *adder = [*adder stringByAppendingFormat:@"-%d-", a];

        NSLog(@"adder: %@", *adder);
        return [*adder stringByAppendingString:appendBlock(a-1, adder)];
    };

    appendBlock(5, &result);

    return result; 
}

基本上,我想创建一个代码块,将数字连接到给定的字符串(加法器)中。结果应该是:"-5--4--3--2--1-".

我在上面的代码中遇到了一个分段错误,但是对于我为树遍历编写的一些其他代码,加法器字符串基本上没有得到更新。关于我在这里做错了什么的任何指示? (是否有可能不允许由内部块(内部递归)更新的变量,因为它已经被外部块占用,或者只是 NSString 是非可变数据类型?)

无论如何,我想保持功能设计不变;我将如何解决这个问题(使用 c/objective)?

经过一番搜索和试验,我找到了解决此问题的方法。

  1. 没有理由在块中为您的 adder 参数使用双指针。只需使用常规指针并相应地更新您的代码。
  2. 错误是因为在块内部,appendBlockNULL 并且您最终解引用了试图调用它的 NULL 指针。

这是一个有效的更新版本:

- (NSString *)someWrapperFunction
{
    NSString *result = @"";

    NSString *(^appendBlock)(int, NSString *);
    __block __weak NSString *(^weakBlock)(int, NSString *);
    weakBlock = appendBlock = ^NSString *(int a, NSString *adder){
        NSString *(^innerBlock)(int, NSString *) = weakBlock;
        if (a == 0)
        {
            // base case
            return @"";
        }

        NSLog(@"%d", a);

        adder = [adder stringByAppendingFormat:@"-%d-", a];

        NSLog(@"adder: %@", adder);

        // Split this update to make it easier to debug.
        NSString *update = innerBlock(a-1, adder);
        return [adder stringByAppendingString:update];
    };

    appendBlock(5, result);

    return result; 
}

输出:"-5--4--3--2--1-"

此更新针对第 1 点进行了重写(这实际上与您的原始问题无关。

为了解决第 2 点,此更新创建了原始 appendBlock 变量以及对同一块的新 __block __weak weakBlock 引用。然后在块内部,创建一个新的(强)块指针来引用弱块指针。在不使用弱指针的情况下,代码可以运行但会导致警告。