Выпуск NSError: сообщение отправлено в освобожденный экземпляр

Я получаю сбой в приложении iOS 7 со следующей ошибкой:

-[NSError release]: message sent to deallocated instance 0x3c443fe0

Ошибка инициируется, когда я добавляю вызов следующего метода:

-(void)loadMessages:(NSString*)customerUID {
  NSString *formatUID = [NSString stringWithFormat:@"%s%@%s", "'", customerUID, "'"];
  formatUID = [formatUID stringByReplacingOccurrencesOfString:@"'" withString:@"%27"];
  NSString *servicePath = [NSString stringWithFormat:@"/api/messagerecipient?messageid=null&customeruid=%@", formatUID];

  [[RKObjectManager sharedManager] getObjectsAtPath:servicePath parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *messagesResult)
  {
    NSArray *messageResults = messagesResult.array;

    if (messageResults != nil || [messageResults count] != 0)
    {
      //Add some code here
    }
  } failure:^(RKObjectRequestOperation *operation, NSError *error) {

    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"An Error Has Occurred" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alertView show];
  }];
}

Я добавил несколько точек останова в код в разных точках, и он не возвращает никаких сведений об ошибке. Кроме того, ничто в журнале консоли не указывает, в чем проблема (я добавил полное ведение журнала RestKit), только приведенное выше сообщение о выпуске NSError.

Я также запустил сканирование зомби в «Инструментах». Он показывает следующее.

Инструменты

Я сбит с толку, потому что это показывает, что зомби создается вызовом GSEventRunModal. Когда я перехожу к расширенным сведениям и выбираю вызов, он показывает следующее:

Расширенная информация

Любые указатели будут с благодарностью оценены, спасибо.

Обновление: трассировка стека расширенных сведений о приборе

введите здесь описание изображения


person Dancer    schedule 17.03.2014    source источник
comment
Итак, что заставляет вас думать, что это связано с RestKit? Если вы не сделаете этот вызов RestKit, значит, у вас нет проблем?   -  person Wain    schedule 18.03.2014
comment
Да, это правильно, но не уверен, что это связано с RestKit. Последняя сработавшая точка останова находится в методе AFURLConnectionOperation, operationDidStart. Процесс, который, кажется, выдает ошибку, называется _CFRunLoopRun.   -  person Dancer    schedule 18.03.2014
comment
Ваше сопоставление должно создавать управляемые объекты и вставлять их в хранилище? Какой несохраненный контент у вас есть, когда вы делаете этот запрос? Что еще вы делаете с Core Data одновременно?   -  person Wain    schedule 18.03.2014
comment
Было бы полезно увидеть всю трассировку стека из расширенной панели сведений для сайта, где был выделен NSError.   -  person rob mayoff    schedule 18.03.2014
comment
Зомби не создается GSEventRunModal. Когда вы видите релиз в GSEventRunModal, это означает, что пул авторелиза опустошается. Последняя строка в вашей истории событий (строка 7) — это дополнительное освобождение (отправленное NSError, ставшему зомби в строке 6), потому что NSError автоматически выпускалось слишком много раз.   -  person rob mayoff    schedule 18.03.2014
comment
Контроллеры ManagedObjectContext не претерпели изменений до вызова метода. Журнал консоли показывает, что операция сопоставления объектов прошла успешно, но объекты не добавляются в хранилище. Кроме того, отсутствует журнал получения заголовков запроса/ответа в/из службы.   -  person Dancer    schedule 18.03.2014
comment
Я добавил расширенную трассировку стека сведений к исходному сообщению.   -  person Dancer    schedule 18.03.2014
comment
Можете ли вы поделиться своей реализацией метода getObjectsAtPath?   -  person Bikramjit Singh    schedule 25.03.2014
comment
ссылка на эту проблему может помочь решить вашу проблему github.com/RestKit/RestKit/issues/1140 Переименование HTTPError в HTTPError1 и создание свойства @synthesized решает проблему.   -  person vin    schedule 26.03.2014
comment
где возникает эта ошибка? в блоке успеха? Блокировка ошибок? или до того, как любой из них называется ?   -  person nsuinteger    schedule 26.03.2014


Ответы (5)


Я тоже много раз это видел, и корень проблемы, похоже, в Core Data. Я использую библиотеку базы данных MagicalRecord (как и RestKit), и мы подумали, что ошибка была там. Вы можете увидеть обсуждение здесь. После всего нашего расследования казалось, что MagicalRecord был прав, а виноваты Core Data.

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

person Mike Gottlieb    schedule 26.03.2014
comment
хотя это не решило мою проблему - ваш ответ помог объяснить, что происходит не так, - следовательно, вы получили награду. Спасибо за вашу помощь! - person Dancer; 27.03.2014

Может быть, вы пытаетесь отобразить AlertView изнутри блока? Взаимодействие с пользовательским интерфейсом должно происходить в основном потоке?

Как отобразить UIAlertView из блока на iOS?< /а>

person Flexicoder    schedule 19.03.2014

Можно попробовать заменить:

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"An Error Has Occurred" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alertView show];

С участием:

NSString * message = [error localizedDescription];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"An Error Has Occurred" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alertView show];

Хотя я предполагаю, что метод init все равно получает строку.

person Rivera    schedule 25.03.2014

Я думаю, что ваша проблема не в самом методе.

в сообщении об ошибке говорится, что вы отправляете вызов освобождения объекту типа NSERROR.

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

или добавьте вызывающий метод к вопросу, чтобы мы его проверили.

person Ahmad Al-Attal    schedule 26.03.2014

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

    -(id)init {
    self = [super init];
    if (self) {
        self.managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        self.managedObjectContext.parentContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
        self.managedObjectContext.retainsRegisteredObjects = YES;
    }

    return self;
}
person Jake Hargus    schedule 10.09.2015