2

在下面的代码中,如果我返回 NSMutableArray 而不是方法的返回类型 NSArray,我不会收到任何警告或编译错误。

但是,使用 -copy 方法将返回值转换为 NSArray 是一种好习惯,如下面的代码?
还是我应该返回 NSMutableArray?

+(NSArray *)returnImutableArray {
    NSMutableArray *arr = [[NSMutableArray alloc] init];
    [arr addObject:@"a"];
    [arr addObject:@"b"];

    //return arr; // no warning
    return [arr copy];
}
4

3 回答 3

6

我认为这本质上是个人喜好。在返回数组之前复制数组会导致(可能很小)性能损失。好处是您将完全防止结果进一步发生突变。但是,我通常不会去麻烦。因为该方法声明的返回类型是不可变的NSArray,所以如果您尝试在其上调用 NSMutableArray 的变异方法之一,编译器会警告您,除非您竭尽全力防止这种情况发生(通过强制转换为 NSMutableArray)。

因此,简而言之,这是个人喜好,我个人通常不会为不可变副本而烦恼。

于 2012-08-27T14:51:21.683 回答
0

这一切都取决于你想用数组实现什么。

如果您真的不想或不需要修改返回的数组,请将其作为 NSArray 返回。您也可以将其作为数组返回,而无需复制它。

在这两种情况下,不要忘记内存管理。

您永远不应该返回保留计数 > 0 的任何内容。

+(NSArray *)returnImutableArray {
    NSMutableArray *arr = [[NSMutableArray alloc] init];
    [arr addObject:@"a"];
    [arr addObject:@"b"];

    NSArray * returnArray = [NSArray arrayWithArray:arr];
    [arr release];
    //return arr; // no warning
    return returnArray;
}

或者你可以这样做:

+(NSArray *)returnImutableArray {
    NSMutableArray *arr = [[NSMutableArray alloc] init];
    [arr addObject:@"a"];
    [arr addObject:@"b"];
    //return arr; // no warning
    return [arr autorelease];
}

无需复制 NSMutableArray,因为它扩展了 NSArray,因此如果这样做,您的代码将永远不会中断。

于 2012-08-27T14:52:11.903 回答
0

默认情况下,我返回一个不可变copy的内部可变实例。不只是NSArray,还有其他几种类型。

我不希望可变对象四处飘荡,尽管只要您将其视为具体对象,它就会发生变异不是问题。

我认为它是一个更好的默认值,因为它可以最大限度地减少共享时的浅拷贝。也就是说,如果您获取结果并将其分配给一个或多个作为copy属性的对象,那么所有这些操作都必须制作具体的浅拷贝,如果它们可以有效地retain. 这与您应该支持copy这些类型的属性而不是retain声明属性时的原因相同。

在某些情况下,您只知道它的范围是有限的,并且可变对象不会出来——在这种情况下,我可能不会费心制作副本。

于 2012-08-27T14:52:31.533 回答