2009-06-10 4 views
2

У меня есть эта проблема с какао, я вызов функции и передачи массива к нему:Передача NSMutableArray в функцию

Некоторые где я вызываю функцию:

[self processLabels:labels]; 

И функция, как следовать:

- (void)processLabels:(NSMutableArray*)labs{ 
    labs = [[NSMutableArray alloc] init]; 
    [labs addObject:@"Random"]; 
.... 
} 

при отладке, я заметил, что ни один новый объект не добавляются к меткам, когда они добавляются в лаборатории. Это потому, что я повторно инициализирую лаборатории? как я мог повторно инициализировать метки внутри функции?

Я попытался с помощью ByRef на это не удалось, любая помощь приветствуется .. благодаря

ответ

1

Заявление labs = [[NSMutableArray alloc] init]; делает labs, чтобы указать на новый массив в рамках метода. Это не означает, что указатель указывает на новый массив.

Если вы хотите изменить указатель вызывающего, сделать что-то вроде этого:

// The caller 
NSMutableArray *labels;   // Don't initialize *labels. 
[self processLabels:&labels]; 

... 

- (void)processLabels:(NSMutableArray**)labs{ 
    *labs = [[NSMutableArray alloc] init]; 
    [*labs addObject:@"Random"]; 
    ... 
} 

Это, вероятно, плохая идея, потому что processLabels: выделяет массив, но вызывающий абонент отвечает за освобождение его.

Если вы хотите, чтобы вызывающий собственный массив, вы могли бы написать processLabels: так:

- (void)processLabels:(NSMutableArray*)labs{ 
    [labs removeAllObjects]; 
    [labs addObject:@"Random"]; 
    ... 
} 

Или, если processLabels: просто возвращает коллекцию этикеток:

- (NSMutableArray*)processLabels { 
    NSMutableArray* labs = [[[NSMutableArray alloc] init] autorelease]; 
    [labs addObject:@"Random"]; 
    ... 
    return labs; 
} 

Если вы хотите вызывающий, ответственный за освобождение массива, удаляет авторекламу. В этом случае соглашение диктует, что имя метода должно начинаться с alloc или new или содержать слово copy.

3

«лаборатории» должны быть инициализированы, прежде чем передать его processLabels, а затем он не должен быть повторно инициализирован ,

Если вы не можете инициализировать массив заранее по какой-либо причине, и вы хотите processLabels создать его, вам нужно передать указатель на указатель:

[self processLabels:&labels]; 

и метод изменится на:

- (void)processLabels:(NSMutableArray**)labs{ 
    *labs = [[NSMutableArray alloc] init]; 
    [*labs addObject:@"Random"]; 
.... 
} 
1

Вам необходимо пройти в изменяемый массив, чтобы иметь возможность изменить его (это определение изменяемых) - превратить NSArray в изменяемый массив, используйте:

NSMutableArray *writableArray = [NSMutableArray arrayWithArray:oldArray]; 

или если вы просто хотите, чтобы сделать пустой изменяемый массив:.

NSMutableArray *writableArray = [NSMutableArray array]; 

Затем передать, что в

2

обычно говорят, что preferrable не миновать изменяемые коллекции, но и обеспечить методы, которые выполняют работу на них ...

Фактически, в ответ на ваш код мне интересно, какая цель заключается в передаче массива «labs» в функцию, когда на самом деле вы просто перезаписываете его (и создаете утечку памяти в обработать). зачем это делать?

+0

Я согласен с тобой. Если у вас есть возврат void, почему бы просто не вернуть массив? – Abizern

1

Будет правильным, как об исправлении существующего метода, так и о том, что это плохая идея. Конечно, возврат к параметру by-reference действителен, и он часто используется в простых программах на C, но в этом случае он добавляет ненужной сложности. В Objective-C предпочтительная идиома состоит в том, чтобы сначала возвращать объекты, используя возвращаемое значение, и сохранять обратно только указатель, если возвращаемое значение уже используется для возврата чего-то еще. Это не только вызовет метод, который легче читать и писать, но он соответствует стандартным идиомам, которые обычно используются на других языках (например, Java и C#). Это становится совершенно очевидным, если вы переписываете указатель на массив, назначая ему, потенциальную ошибку, которая, скорее всего, будет подхвачена такими инструментами, как Clang Static Analyzer.

В соответствующей заметке вы, вероятно, также должны рассмотреть возможность лучшего именования методов и параметров. (Я понимаю, что это, вероятно, несколько надуманный пример.) Если вы обрабатываете «метки», и они исходят из какого-то другого источника, кроме изменяемого массива, который вы создаете, я бы не назвал локальную переменную «labs» или «labs», ярлыки "- используйте более описательное имя. Имена методов, которые менее расплывчаты в отношении того, что они делают, могут значительно улучшить читаемость кода. В Objective-C предпочтительны имена длинного описательного метода. Поскольку Xcode выполняет завершение кода, а имена методов менее неоднозначны, конечным результатом обычно является . ввод текста.

Смежные вопросы