xcode 将 NSMutableArray 传递给函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/975995/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 18:36:37  来源:igfitidea点击:

Passing NSMutableArray into a function

iphoneobjective-ccocoaxcode

提问by

I have this problem with Cocoa, I am calling a function and passing an Array to it:

我对 Cocoa 有这个问题,我正在调用一个函数并将一个数组传递给它:

Some where I call the function:

我调用函数的一些地方:

[self processLabels:labels];

And the function is as follow:

功能如下:

- (void)processLabels:(NSMutableArray*)labs{
    labs = [[NSMutableArray alloc] init];
    [labs addObject:@"Random"];
....
}

When debugging, I notice that no new object are being added to labels when they are added to labs. Is it because I am re-initializing labs? how could I re-initialize labels inside the function then?

调试时,我注意到将标签添加到实验室时没有将新对象添加到标签中。是因为我正在重新初始化实验室吗?那我怎么能重新初始化函数内部的标签呢?

I tried using byref by didn't succeed, any help is appreciated.. thanks

我尝试使用 byref 没有成功,任何帮助表示赞赏..谢谢

采纳答案by Will Harris

The statement labs = [[NSMutableArray alloc] init];makes labsto point to the new array in the scope of the method. It does not make the caller's pointer point to the new array.

该声明labs = [[NSMutableArray alloc] init];使labs以点的方法的范围的新数组。它不会使调用者的指针指向新数组。

If you want to change the caller's pointer, do something like this:

如果要更改调用者的指针,请执行以下操作:

// The caller
NSMutableArray *labels;         // Don't initialize *labels.
[self processLabels:&labels];

...

- (void)processLabels:(NSMutableArray**)labs{
    *labs = [[NSMutableArray alloc] init];
    [*labs addObject:@"Random"];
    ...
}

That's probably a bad idea because processLabels:allocates the array but the caller is responsible for freeing it.

这可能是一个坏主意,因为processLabels:分配了数组但调用者负责释放它。

If you want the caller to own the array, you could write processLabels:like this:

如果您希望调用者拥有该数组,您可以这样写processLabels:

- (void)processLabels:(NSMutableArray*)labs{
    [labs removeAllObjects];
    [labs addObject:@"Random"];
    ...
}

Or, if processLabels:is just returning a collection of labels:

或者,如果processLabels:只是返回一组标签:

- (NSMutableArray*)processLabels {
    NSMutableArray* labs = [[[NSMutableArray alloc] init] autorelease];
    [labs addObject:@"Random"];
    ...
    return labs;
}

If you want the caller to be responsible for freeing the array, remove the autorelease. In that case, convention dictates that the method name should start with allocor new, or contain the word copy.

如果您希望调用者负责释放数组,请删除自动释放。在这种情况下,约定规定方法名称应以alloc或开头new,或包含单词copy

回答by Chris Karcher

'labs' should be initialized before you pass it to processLabels, and then it shouldn't be re-initialized.

'labs' 应该在你将它传递给 processLabels 之前被初始化,然后它不应该被重新初始化。

If you can't initialize the array beforehand for whatever reason and you want processLabels to create it, you need to pass a pointer to a pointer:

如果由于某种原因无法事先初始化数组,并且希望 processLabels 创建它,则需要传递一个指向指针的指针:

[self processLabels:&labels];

and the method would change to:

并且该方法将更改为:

- (void)processLabels:(NSMutableArray**)labs{
    *labs = [[NSMutableArray alloc] init];
    [*labs addObject:@"Random"];
....
}

回答by kent

generally spoken, it is preferrable to not pass mutable collections, but to provide methods which perform work on them...

一般来说,最好不要传递可变集合,而是提供对它们执行工作的方法......

in fact, in response to your code I wonder even what the purpose is of passing the 'labs' array into the function when in fact you are just overwriting it (and creating a memory leak in the process). why do that?

事实上,为了响应您的代码,我什至想知道将 'labs' 数组传递给函数的目的是什么,而实际上您只是覆盖它(并在此过程中造成内存泄漏)。为什么要这样做?

回答by Quinn Taylor

Will is correct, both about correcting the existing method, and about it being a bad idea. Storing back to a by-reference parameter is certainly valid, and it's used frequently in plain C programs, but in this case it adds needless complexity. In Objective-C, the preferred idiom is to return objects using the return value first, and only store back to a pointer if the return value is already being used to return something else. Not only will this make calls to a method easier to read and write, but it conforms to standard idioms that are commonly used in other languages (such as Java and C#). It becomes quite obvious if you overwrite an array pointer by assigning to it, a potential bug that is more likely to be picked up by tools like the Clang Static Analyzer.

Will 是正确的,无论是关于纠正现有方法,还是关于它是一个坏主意。存储回按引用参数当然是有效的,它在普通 C 程序中经常使用,但在这种情况下,它增加了不必要的复杂性。在 Objective-C 中,首选的习惯用法是首先使用返回值返回对象,如果返回值已被用于返回其他内容,则仅将其存储回指针。这不仅会使对方法的调用更易于读写,而且符合其他语言(例如 Java 和 C#)中常用的标准习惯用法。如果您通过分配给数组指针来覆盖它,这将变得非常明显,这是一个潜在的错误,更有可能被Clang 静态分析器之类的工具发现。

On a related note, you should probably also consider better method and parameter naming. (I realize this is likely a somewhat contrived example.) If you're processing "labels", and they come from some source other than the mutable array you're creating, I wouldn't name the local variable "labs" or "labels" — use a more descriptive name. Method names that are less vague about what they do can vastly improve code readability. In Objective-C, long descriptive method names are preferred. Since Xcode does code completion and the method names are less ambiguous, the end result is usually lesstyping.

在相关说明中,您可能还应该考虑更好的方法和参数命名。(我意识到这可能是一个有点人为的例子。)如果您正在处理“标签”,并且它们来自您正在创建的可变数组以外的其他来源,我不会将局部变量命名为“labs”或“标签”——使用更具描述性的名称。对它们所做的事情不那么模糊的方法名称可以极大地提高代码的可读性。在 Objective-C 中,长的描述性方法名称是首选。由于 Xcode 会完成代码补全并且方法名称不那么模糊,因此最终结果通常是更少的输入。

回答by Kendall Helmstetter Gelner

You need to pass in a mutable array to be able to change it (that's the definition of Mutable) - to turn an NSArray into a mutable array, use:

您需要传入一个可变数组才能更改它(这是 Mutable 的定义) - 要将 NSArray 转换为可变数组,请使用:

NSMutableArray *writableArray = [NSMutableArray arrayWithArray:oldArray];

or if you just want to make an empty mutable array:

或者,如果您只想创建一个空的可变数组:

NSMutableArray *writableArray = [NSMutableArray array];

Then pass that in.

然后传进去。