我有Cocoa的这个问题,我正在调用一个函数并将一个数组传递给它:
我调用函数的地方:
[self processLabels:labels];
功能如下:
- (void)processLabels:(NSMutableArray*)labs{
labs = [[NSMutableArray alloc] init];
[labs addObject:@"Random"];
....
}
调试时,我注意到标签添加到实验室时没有添加新对象。是因为我正在重新初始化实验室吗?我怎么能重新初始化函数内的标签呢?
我尝试使用byref未成功, 任何帮助表示赞赏.. 感谢
答案 0 :(得分:3)
'labs',然后不应该重新初始化它。
如果由于某种原因无法预先初始化数组,并且您希望processLabels创建它,则需要将指针传递给指针:
[self processLabels:&labels];
,方法将更改为:
- (void)processLabels:(NSMutableArray**)labs{
*labs = [[NSMutableArray alloc] init];
[*labs addObject:@"Random"];
....
}
答案 1 :(得分:2)
一般来说,最好不要传递可变集合,而是提供对它们进行工作的方法......
事实上,在回应你的代码时,我甚至想知道将'labs'数组传递给函数的目的是什么,实际上你只是覆盖它(并在进程中创建内存泄漏)。为什么这样做?
答案 2 :(得分:1)
你需要传入一个可变数组才能更改它(这是Mutable的定义) - 要将NSArray转换为可变数组,请使用:
NSMutableArray *writableArray = [NSMutableArray arrayWithArray:oldArray];
或者如果你只想制作一个空的可变数组:
NSMutableArray *writableArray = [NSMutableArray array];
然后传入。
答案 3 :(得分:1)
语句labs = [[NSMutableArray alloc] init];
使labs
指向方法范围内的新数组。它不会使调用者的指针指向新数组。
如果您想更改呼叫者的指针,请执行以下操作:
// The caller
NSMutableArray *labels; // Don't initialize *labels.
[self processLabels:&labels];
...
- (void)processLabels:(NSMutableArray**)labs{
*labs = [[NSMutableArray alloc] init];
[*labs addObject:@"Random"];
...
}
这可能是一个坏主意,因为processLabels:
分配了数组,但调用者负责释放它。
如果您希望调用者拥有该数组,您可以像这样编写processLabels:
:
- (void)processLabels:(NSMutableArray*)labs{
[labs removeAllObjects];
[labs addObject:@"Random"];
...
}
或者,如果processLabels:
只是返回一组标签:
- (NSMutableArray*)processLabels {
NSMutableArray* labs = [[[NSMutableArray alloc] init] autorelease];
[labs addObject:@"Random"];
...
return labs;
}
如果您希望调用者负责释放阵列,请删除自动释放。在这种情况下,约定规定方法名称应以alloc
或new
开头,或包含单词copy
。
答案 4 :(得分:1)
对于纠正现有方法以及这是一个坏主意,这是正确的。存储回by-reference参数当然是有效的,并且它在普通的C程序中经常使用,但在这种情况下它会增加不必要的复杂性。在Objective-C中,首选的习惯是首先使用返回值返回对象,如果返回值已经被用于返回其他内容,则仅存储回指针。这不仅会使对方法的调用更容易读写,而且还符合其他语言(例如Java和C#)中常用的标准习语。如果你通过赋值来覆盖一个数组指针,那么很明显,这个潜在的错误更有可能被像Clang Static Analyzer这样的工具选中。
在相关的说明中,您可能还应该考虑更好的方法和参数命名。 (我意识到这可能是一个有点人为的例子。)如果你正在处理“标签”,并且它们来自你正在创建的可变阵列以外的某些来源,我不会将局部变量命名为“labs”或“标签“ - 使用更具描述性的名称。对其内容不太模糊的方法名称可以极大地提高代码的可读性。在Objective-C中,首选长描述性方法名称。由于Xcode完成代码并且方法名称不那么模糊,因此最终结果通常是 less 输入。