Передача массива по ссылке в Objective-C - PullRequest
4 голосов
/ 30 мая 2010

Я хотел бы передать NSMutableArray по ссылке, чтобы он мог быть изменен другим методом. Какой будет правильный синтаксис для этого?

Спасибо

Ответы [ 3 ]

17 голосов
/ 30 мая 2010

Объекты 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-параметров обычно наблюдается только в том случае, если возвращаемое значение уже используется и дополнительная информация должна быть возвращена. Примером может служить информация об ошибках, как заметил сонакс.

4 голосов
/ 31 мая 2010

В дополнение к ответу Георга Фриче, возможно, стоит отметить, что некоторые методы ожидают получения адреса указателя объекта. Например:

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).

0 голосов
/ 28 января 2016

Как сказал Георг Фрицше, 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"];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...