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)?
经过一番搜索和试验,我找到了解决此问题的方法。
- 没有理由在块中为您的
adder
参数使用双指针。只需使用常规指针并相应地更新您的代码。
- 错误是因为在块内部,
appendBlock
是 NULL
并且您最终解引用了试图调用它的 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
引用。然后在块内部,创建一个新的(强)块指针来引用弱块指针。在不使用弱指针的情况下,代码可以运行但会导致警告。
我正在对树遍历进行一些修补(我已经以更直接的方式解决了这个问题)但是我在以下 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)?
经过一番搜索和试验,我找到了解决此问题的方法。
- 没有理由在块中为您的
adder
参数使用双指针。只需使用常规指针并相应地更新您的代码。 - 错误是因为在块内部,
appendBlock
是NULL
并且您最终解引用了试图调用它的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
引用。然后在块内部,创建一个新的(强)块指针来引用弱块指针。在不使用弱指针的情况下,代码可以运行但会导致警告。