在Objective-C中如何通过引用传递数组

5

我想通过引用传递一个NSMutableArray,以便它可以被另一个方法修改。正确的语法是什么?

谢谢。

3个回答

18

Objective-C对象始终通过引用(使用指针)传递 - 您无法按值传递它们。

也就是说,以下方式是可以的:

- (void)mutateArray:(NSMutableArray*)array {
    // alter array ...
}

...并且可以像这样调用:

NSMutableArray *array = ...;
[self mutateArray:array];

还有一种可能是通过引用传递指针:

- (void)newArray:(NSMutableArray **)array;

在这种情况下,array被用作输出参数——你传递一个指向指针的引用来接收一个实例:

- (void)newArray:(NSMutableArray **)array {
    *array = [[NSMutableArray alloc] init];
}

...可以这样调用:

NSMutableArray *array = nil;
[self newArray:&array];

如果返回值已经被使用并且需要返回附加信息,通常会使用out参数。正如dreamlax所指出的那样,一个例子是错误信息。


当在方法声明中出现以下内容时,它是什么意思(以您上面的代码为例):“-(void)mutateArray:(NSMutableArray **)array;”? - Garry Pettet

4
除了Georg Fritzche的回答之外,值得注意的是,一些方法希望给出对象指针的地址。例如:
NSError *anError; // points to garbage now
NSStringEncoding enc;
NSString *aString = [NSString stringWithContentsOfFile:@"/some/file.txt"
                                          usedEncoding:&enc
                                                 error:&anError];

if (aString == nil)
{
    // anError now points to an initialised NSError object.
}

这可能会变得棘手,因为一些记录的方法要求您释放以此方式获取的对象,而有些则不需要(如果需要显式释放的示例,请参见NSPropertyListSerialization)。


任何需要您以这种方式释放返回指针的方法应该有明确的文档,因为它违反了Cocoa引用计数内存管理的基本规则。 - JeremyP

1
正如Georg Fritzsche所说,NSMutableArray会自动按引用传递,但NSArray不会。最好的选择是查看下面的代码:
void mutateImmutableArray(NSArray *array);
void mutateMutableArray(NSMutableArray *array);
void mutateImmutableArrayByRef(NSArray **array);
void mutateMutableArrayByRef(NSMutableArray **array);

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //Change immutable array in method that expects immutable array
        NSArray *immutable = @[@1,@2,@3];
        mutateImmutableArray(immutable);
        NSLog(@"After 1: %@",immutable); // 1,2,3

        //Change mutable array in method that expects immutable array
        NSMutableArray *mutable = [@[@1,@2,@3]mutableCopy];
        mutateImmutableArray(mutable); 
        NSLog(@"After 2: %@",mutable); //1,2,3

        //Change mutable array in method that expects mutable array
        mutable = [@[@1,@2,@3]mutableCopy];
        mutateMutableArray(mutable); 
        NSLog(@"After 3: %@",mutable); //1,2,3, Four

        //Change immutable array in method that expects immutable array by reference
        immutable = @[@1,@2,@3];
        mutateImmutableArrayByRef(&immutable); 
        NSLog(@"After 4: %@",immutable); //4,5,6

        //Change mutable array in method that expects mutable array by reference
        mutable = [@[@1,@2,@3]mutableCopy];
        mutateMutableArrayByRef(&mutable); 
        NSLog(@"After 5: %@",mutable); //1,2,3, Four

    }
    return 0;
}

void mutateImmutableArray(NSArray *array)
{
    array  = @[@4,@5,@6];
}

void mutateImmutableArrayByRef(NSArray **array)
{
    *array  = @[@4,@5,@6];
}

void mutateMutableArray(NSMutableArray *array)
{
    [array addObject:@"Four"];
}

void mutateMutableArrayByRef(NSMutableArray **array)
{
    [*array addObject:@"Four"];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接