Объект был вероятно изменен после освобождения

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

iGreenAppDelegate *delegate = [UIApplication sharedApplication].delegate;
if(checkInViewController) {
    [checkInViewController release];
    checkInViewController = nil;
}
checkInViewController = [[CheckInViewController alloc] initWithCheckpoint:checkpoint];

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.8];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:[delegate window] cache:YES];
[[delegate rootTabBarController].view removeFromSuperview];
[[delegate window] addSubview:checkInViewController.view];
[UIView commitAnimations];

Проблема - второй раз, когда я запускаю UIViewController, я хочу выпустить его, чтобы избежать утечки памяти. Отладчик отображает

iGreen(916,0x3f60348c) malloc: ошибка для объекта 0x130350: неверная контрольная сумма для освобожденного объекта - объект, вероятно, был изменен после освобождения. установить точку останова в malloc_error_break для отладки

Это странно, потому что подобные коды в других частях не возвращают такую ​​ошибку. Более того, я пробовал авто-релиз, но программа немедленно вылетает, и отладчик говорит, что я изменяю финализированные слои.

Я работал над этой проблемой целую ночь и все еще не понимал ее.

4 ответа

Установите точку останова в malloc_error_break для отладки.

Сделайте это и опубликуйте обратную трассировку.

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

Помимо установки точки останова в malloc_error_break - нажмите Command-6 в xCode, чтобы перейти на вкладку точек останова, - также включите вспомогательные средства malloc в своей схеме.

Перейдите в селектор схем, выберите "Редактировать схему", найдите цель "Выполнить" и перейдите на вкладку "Диагностика". Ниже управление памятью включает каракули, защитные края, охраняемые объекты malloc и zombie.

Если повезет, xCode поймает вас на том, что вы пишете за пределами выделенной памяти и разрушаете память.

Это как наблюдение взрослых за работой с памятью...

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

Каждый раз, когда код в этом фрагменте запускается, он освобождает (освобождает) любой существующий checkinViewController и выделяет новый, и, очевидно, он никогда больше не касается старого. Но у кого еще может быть указатель на старый объект?

Возможно, другой код, который вы написали, и, возможно, [окно делегата], которое получает ссылку через "[[окно делегата] addSubview:checkInViewController.view];"? Надеюсь, что последняя использует свою собственную ссылку, то есть релиз не сразу ее освободит.

Но следите за тем, куда бы вы ни копировали этот указатель, не добавляя ссылку. Если вы делаете это где-то, а затем в другом месте (например, в приведенном выше фрагменте), кто-то вызывает release по тому же указателю, у вас теперь может быть указатель на освобожденный объект.

В вашем коде есть пара вещей, которые не подходят для дизайна. Сначала вы выпускаете checkInViewController, не удаляя его представление из своего суперпредставления (если оно есть), затем вы удаляете представление rootTabBarController из его суперпредставления, ничего не делая с самим контроллером, и не добавляете checkInViewController к rootTabBarController или свойству rootViewController. окна, так что он в воздухе (просто сохраняется вашим текущим объектом). Что происходит, когда этот (текущий) объект освобождается, но представление checkInViewController остается (сохраняется) в окне?

Если вы отпустите свой checkInViewController, но его окно все еще будет сохранено в окне, это, вероятно, создаст некоторые проблемы...

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

Другие вопросы по тегам