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

时间:2010-05-30 17:58:15

标签: objective-c cocoa syntax

我想通过引用传递NSMutableArray,以便可以通过其他方法更改它。这个的正确语法是什么?

谢谢,

3 个答案:

答案 0 :(得分:17)

Objective-C对象总是通过引用传递(使用指针) - 你不能按值传递它们。

即。以下是好的:

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

......并且可以是例如像这样调用:

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

还可以通过引用传递指针:

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

在这种情况下,array用作out参数 - 您传递对指针的引用以接收实例:

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

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

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

通常只有在已经使用了返回值并且必须返回其他信息时才会看到使用out参数。一个例子就是像dreamlax所说的错误信息。

答案 1 :(得分: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)。

答案 2 :(得分:0)

正如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"];
}