【问题标题】:Passing NSMutableArray into a function将 NSMutableArray 传递给函数
【发布时间】:2010-11-01 20:06:22
【问题描述】:

我在 Cocoa 中遇到了这个问题,我正在调用一个函数并将一个数组传递给它:

我调用函数的地方:

[self processLabels:labels];

功能如下:

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

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

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

【问题讨论】:

    标签: iphone objective-c cocoa xcode


    【解决方案1】:

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

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

    [self processLabels:&labels];
    

    并且方法将更改为:

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

    【讨论】:

      【解决方案2】:

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

      NSMutableArray *writableArray = [NSMutableArray arrayWithArray:oldArray];
      

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

      NSMutableArray *writableArray = [NSMutableArray array];
      

      然后传入。

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

        • 我同意你的看法。如果你有一个 void 返回,为什么不直接返回数组呢?
        【解决方案4】:

        语句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;
        }
        

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

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-01-14
            • 2014-07-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多