Печать NSMutableArray вызывает сбой без кода ошибки - PullRequest
0 голосов
/ 13 января 2011

Я определил, что мое приложение падает в следующей строке:

if(sourceValues != nil && [sourceValues class] == [NSMutableArray class])
    [sourceValues release];

"sourceValues" объявлен как NSMutableArray в верхней части моего класса.Цикл if выполняется, и выполняется вызов [sourceValues ​​release], что приводит к сбою программы без кода ошибки.Итак, поскольку sourceValues! = Nil и поскольку [sourceValues ​​class] == [NSMutableArray class], я хотел точно узнать, что такое sourceValues.Итак, над циклом «if» я добавил следующее:

NSLog(@"sourceValues is %@", sourceValues);

Но моя программа не будет его печатать.Он просто падает без кода ошибки в этой строке.Итак, если sourceValue существует и если это NSMutableArray, почему он не будет напечатан.В чем здесь проблема?

Я пытаюсь получить код, который говорит: «Если было выделено sourceValues, отпустите его».Как я могу это сделать?

Ответы [ 4 ]

1 голос
/ 13 января 2011

Если это ...

NSLog(@"sourceValues is %@", sourceValues);

... сбой вашей программы, это потому, что sourceValues уже выпущен.Где бы вы ни release sourceValues, установите его на nil.

[sourceValues release], sourceValues = nil;

Если ваше приложение все еще падает, это потому, что массив был переиздан где-то еще.То есть вы не правильно сбалансировали удержания и выпуски.Сначала попробуйте «построить и проанализировать» и исправить все проблемы, которые выявляет статический анализатор.Затем включите обнаружение зомби и посмотрите, где вы впервые отправляете сообщения об освобожденном объекте.

Обратите внимание, что [sourceValues class] == [NSMutableArray class] не будет работать, и этот шаблон никогда не следует использовать для проверки того, принадлежит ли экземпляр определенному классу.,Вы всегда должны использовать isKindOfClass: или isMemberOfClass:.

Однако, поскольку вы все равно не можете различить изменяемый или неизменяемый массив, нет смысла проверять в первую очередь.

1 голос
/ 13 января 2011

Почему бы не использовать:

if(sourceValues != nil && [sourceValues isKindOfClass:[NSMutableArray class]])
    [sourceValues release];

Вы можете использовать другие методы, такие как:

  • isMemberOfClass:
0 голосов
/ 13 января 2011

Ну, во-первых, нет опасности в освобождении объекта nil.Так что вопрос «если sourceValues ​​был выделен, отпустите его».вероятно, излишни.Если вы не заняты чем-то напуганным, вам следует следовать обычным правилам управления памятью и просто вызывать [sourceValues release]; в dealloc

Вы пробовали запускать все с включенными точками останова («Сборка и отладка - точки останова включены» вXcode)?Это обычно дает вам больше отладочной информации, чем обычное «Построение и запуск».

Может быть (я предполагаю, основываясь на некоторых странных проблемах, которые у меня были в прошлом), что вы на самом деле исправили sourceValues, но указатель все еще указывает на свою старую память.Если это произойдет, новый объект может быть расположен в той области, которую программа все равно будет пытаться обрабатывать как NSMutableArray.

0 голосов
/ 13 января 2011

Попробуйте проверить retainCount, что-то вроде:

NSLog (@ "счетчик сохранения:% d", [sourceValues ​​retainCount]);

Используйте ТОЛЬКО для тестирования / отладки, не полагайтесь на это в операторе if.

Кроме того, вы можете попробовать перебрать sourceValues ​​и распечатать его содержимое в NSLog, но я понятия не имею, что там.

Лучшее, что нужно сделать, это настроить свойство класса как MSMutableArray с помощью RETAIN и использовать синтез. Сделка позаботится о выпуске.

Если вышеизложенное реализовано, вы можете распределить / инициализировать следующим образом:

self.sourceValues = [[[NSMutableArray alloc] init] autorelease];

, а затем добавляйте объекты непосредственно в self.sourceValues ​​по мере необходимости. Не нужно беспокоиться об освобождении, это будет сделано в dealloc.

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