NSMutableArray поврежден - PullRequest
       5

NSMutableArray поврежден

1 голос
/ 02 марта 2009

Я делаю приложение для iPhone, которое использует навигационный элемент управления для просмотра некоторых данных. Эти данные хранятся в базе данных sqlite, и у меня есть класс, который получает их и возвращает их в NSMutableArray из NSStrings.

Проблема в том, что на первом экране навигации все работает безупречно, но на втором экране (другой вид, который выдвигается) тот же код завершается ошибкой, потому что NSMutableArray поврежден. В отладчике я вижу, что он возвращается правильно, но когда пришло время его использовать, указатели повредились, и приложение перестало работать.

Я установил точки останова во всех своих функциях и нигде не вижу, где они могут быть повреждены. И поскольку первое представление, которое использует тот же точный код, даже обращаясь к одним и тем же таблицам eact, работает правильно, я не знаю, где искать.

Если кто-то захочет взглянуть на код, я загрузил его на мой сайт: http://sachafuentes.com/iBacus.zip

Заранее спасибо.

UPDATE:

Проблема заключается в функции получения данных, которая выглядит следующим образом (это упрощенная версия с некоторым псевдокодом).

-(NSMutableArray *) getPaises {
 NSMutableArray * paises;
 paises = [[NSMutableArray alloc] init];
 while( get new row ) {
  NSString *aPais = get the value;
  [paises addObject:aPais];
  [aPais release];
 }
 return paises;
}

Если я закомментирую [релиз aPais], все будет работать, но для меня это выглядит как утечка памяти, поскольку строка NSString не будет выпущена.

Ответы [ 5 ]

3 голосов
/ 02 марта 2009

Хорошо, вот проблема:

NSString *aPais = [NSString stringWithUTF8String:(char*)sqlite3_column_text(compiledStatement, 0)];

По соглашению, в любое время, когда вы видите alloc и init, вам нужно release где-нибудь в будущем.

По соглашению, всякий раз, когда вы используете метод стиля xWithX:, результирующий объект будет освобожден для вас.

Следовательно, это утверждение:

[aPais release];

вызовет сбой вашего метода, поскольку объект освобождается раньше, чем должен быть. Просто удалите эту строку, установите для NSMutableArray экземпляр значение autorelease -d, и вы получите лучшие результаты.

1 голос
/ 02 марта 2009

Любой объект, который у вас alloc и init должен быть release -d, когда вы закончите с ним, иначе у вас будет утечка памяти.

Поскольку вы передаете ссылку вне области действия getPaises, вы должны автоматически освободить NSMutableArray, иначе у вас будет утечка памяти:

paises = [[[NSMutableArray alloc] init] autorelease];

Не могли бы вы уточнить этот шаг здесь:

NSString *aPais = get the value;

Непонятно, что происходит в "get the value", и я подозреваю, что это одна из причин нестабильности.

1 голос
/ 02 марта 2009

Я вижу, что код (дословно)

while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
    NSString *aPais = [NSString stringWithUTF8String:
                       (char*)sqlite3_column_text(compiledStatement, 0)];
    [paises addObject:aPais];
    [aPais release];
}

... и это именно так, как @gs говорит. aPais автоматически выпущен и не должен выпускаться.

1 голос
/ 02 марта 2009

Ищите неправильно управление памятью , это наиболее вероятная причина сбоев. Я думаю, что вы выпускаете свои объекты куда-то, где не должны, и поэтому у вас есть висячие указатели в массиве.

Update1

[aPais release] неверно, так как вы нигде не сохраняете его в этом методе. Возвращаемые значения всегда должны быть автоматически освобождены. В вашем коде должно быть то же количество retain, что и release.

(Некоторые люди утверждают, что retain также может быть alloc init, но я всегда стараюсь использовать alloc init autorelease, но это вопрос стиля.)

КСТАТИ

Вы должны автоматически высвобождать свой массив, вы сохраняете его здесь только с [[alloc] init].

0 голосов
/ 13 декабря 2009

Вы также можете использовать вспомогательный конструктор для инициализации NSMutableArray:

NSMutableArray *paises = [NSMutableArray array];

Это эквивалентно выполнению:

NSMutableArray *paises = [[[NSMutableArray alloc] init] autorelease];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...