NSMutableArrays - PullRequest
       2

NSMutableArrays

2 голосов
/ 26 августа 2009

У меня есть NSMutableArray в качестве переменной-члена для класса.

В файле .h:

@interface bleh {
NSMutableArray *list;
}

@property (readonly, assign) NSMutableArray *list;

@end

В файле .m:

@implementation bleh
@synthesize list;
-(void)init;
{
    list = [NSMutableArray arrayWithCapacity:30];
}
@end

Теперь я не программист на объективном C, поэтому, возможно, мне не хватает некоторых нюансов, но когда я делаю следующее:

NSMutableString *listItem = [NSMutableString stringWithString:@"Foobar"];
[list addObject:listItem];

У меня странное поведение. А именно, я использую это, чтобы сохранить список файлов, которые я в конечном итоге хочу прикрепить к электронному письму, а затем открыть средство выбора. Я получаю SIGABRT, и после отладки я обнаруживаю, что всякий раз, когда я оперирую списком, я ничего не получаю. Сообщения addObject вообще не увеличивают размер NSMutableArray.

Я что-то упустил? Может кто-нибудь показать мне полную реализацию настройки NSMutableArray для манипулирования внутри класса в Objective C?

Спасибо.

PS - Предположим, что я достаточно умен, чтобы поместить манипуляции с NSMutableArray в функцию-член для класса, содержащего переменную-член.

Ответы [ 8 ]

4 голосов
/ 23 сентября 2015

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

не забудьте инициализировать ваш массив

NSMutableArray *array = [[NSMutableArray alloc] init];

исправить (только чтение, назначить),

3 голосов
/ 26 августа 2009

Ваша переменная list была автоматически освобождена и удалена, поэтому ваша программа вылетает при попытке доступа к ней.

Существует два способа создания объектов в Какао:

NSMutableArray* array1 = [[NSMutableArray alloc] initWithCapacity:10];
NSMutableArray* array2 = [NSMutableArray arrayWithCapacity:10];

array1 был создан с помощью alloc + init, поэтому он принадлежит вам. Он будет держаться до тех пор, пока вы не release это.

array2 не был создан с помощью alloc + init, поэтому вы не являетесь его владельцем. Вы не несете ответственности за его освобождение, но оно само исчезнет. Вы должны сохранить array2, если хотите, чтобы он оставался рядом.

3 голосов
/ 26 августа 2009

Ваша декларация list не позволяет вам правильно сохранить NSMutableArray. Вызывая arrayWithCapacity, вы фактически помещаете массив в пул автоматического выпуска, что означает, что он может быть освобожден в любое время, если ни один объект не заинтересован в его сохранении. В то время как вы, заявленные вами вещи не отражают это:

@property (readonly, assign) NSMutableArray *list;

В приведенном выше объявлении просто указывается, что этот указатель является копией другого указателя - он не требует управления памятью. Вместо этого следует читать:

@property (readonly, retain) NSMutableArray *list;

... и вы должны назначить список следующим образом:

self.list = [NSMutableArray arrayWithCapacity:64];

Поскольку вы указываете атрибут retain для свойства, всякий раз, когда ему присваивается новое значение, сообщение retain отправляется этому новому значению, сообщая диспетчеру памяти, что вы не хотите, чтобы этот объект был освобожден. Чтобы привести этот полный круг, вам нужно release объект, когда вы содержите класс освобожден:

- (void)dealloc
{
    [list release];
    [super dealloc];
}
3 голосов
/ 26 августа 2009

Вы создаете массив с помощью arrayWithCapacity:, который возвращает массив, который вам не принадлежит, и вы никогда не претендуете на владение им. Используйте средство доступа к свойству, чтобы сохранить массив:

self.list = [NSMutableArray arrayWithCapacity:30];

Я бы порекомендовал прочитать Документы по управлению памятью Какао . Как только вы узнаете там правила, станет ясно, что делать в такой ситуации. Они не очень сложные, но они очень необходимы, если вы собираетесь программировать Cocoa.

3 голосов
/ 26 августа 2009

Как вы на самом деле создаете свой массив? Возможно ли, что он автоматически выпускается и уходит? Помните, что если вы создаете его с помощью удобного метода (например, array или чего-то еще), вам нужно retain.

1 голос
/ 26 августа 2009

Проблема ehre (при условии, что вы правильно инициализируете свой массив) может заключаться в том, что @"Foobar" дает NSString, а не NSMutableString, поэтому он терпит неудачу, потому что если разные типы вы должны сделать

 NSMutableString *listItem = [NSMutableString stringWithString:@"Foobar"];
    [list addObject:listItem];

или

  NSString *listItem =@"FooBar";
        [list addObject:listItem];
1 голос
/ 26 августа 2009

Вы правильно инициализируете свой список? Т.е. в вашем коде есть что-то вроде следующего?

list = [[NSMutableArray alloc] init];
0 голосов
/ 26 августа 2009

Не похоже, что вы на самом деле инициализировали NSMutableArray.

В событии init объекта просто скажите

 [self setList:[[NSMutableArray alloc] initWithCapacity:10]]];

(я бы просто сказал init, но я не помню, работает ли это. Не имеет значения, с какой мощности вы начинаете)

Перед фактическим размещением массива переменная list будет иметь значение nil.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...