Передача Массива По Ссылке В Objective-C
Я хотел бы передать NSMutableArray по ссылке, чтобы его можно было изменить другим методом. Каков был бы правильный синтаксис для этого?
Спасибо,
3 ответа:
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-parameters обычно отображается только в том случае, если возвращаемое значение уже используется и требуется вернуть дополнительную информацию. Примером может служить информация об ошибках, как отметил dreamlax.
В дополнение к ответу Георга Фрицше, возможно, стоит отметить, что некоторые методы ожидают, что им будет дан адрес указателя объекта. Например:
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
).
Как сказал Георг Фриц, 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"]; }