Это очень, очень ... очень странная ошибка.Трудно описать конкретный проект, который я имею, но я постараюсь создать более простое представление о моих классах.Это выглядит так:
Предположим, у меня контроллер навигации в качестве контроллера верхнего вида.Внутри него в какой-то момент у меня есть UIViewController, скажем, ContactsScreenController.Представление для этого содержит несколько UITableView, каждый из которых управляется отдельным объектом типа MyTableController (делегат и источник данных).Я делаю это, сохраняя массив контроллеров
// This is the interface for my screen controller. An object of this type goes in a top-
// level navigation controller
// MainScreenController.h
@interface ContactsScreenController : UIViewController
NSMutableArray* tableControllers;
@end
// MainScreenController.m
- (UITableViewCell*)cellForRowAtIndexPath..something..
{
// Here what I do is create a new controller if needed, and add it to tableControllers
// Memory allocations & releases are good because I checked with instruments
}
#define SAFE_DEL(x) { if (x != nil) { [x release]; x = nil; } }
- (void)dealloc
{
SAFE_DEL(tableControllers);
[super dealloc];
}
Теперь MyTableController - более сложный объект, так как он обрабатывает выборку данных из веб-службы, но в основном я хочу получитьчтобы убедиться, что при удалении объекта я отменяю все ожидающие запросы данных, например:
// MyTableController.m
- (void)dealloc
{
[globalDataProvider cancelRequestsForController:self];
// release other objects i might have
[super dealloc];
}
ОК, так что это моя установка объектов.Сбой происходит, когда я удаляю объект tableControllers.Он уменьшает значение retainCount для моих объектов MyTableController и достигает 0 (проверено с помощью инструментов).Но по какой-то НЕИЗВЕСТНОЙ причине я получаю вызовы для cancelRequestsForController, ПОСЛЕ того, как количество сохранений было равно нулю.Очевидно, я получаю EXC_BAD_ACCESS.
Прежде чем вы начнете думать, что это проблема с моими парами сохранения / разблокировки, приложение работает отлично, если я освобождаю контроллер основного экрана, в то время как внутренние таблицы статичны.Как только прокрутка прокручивается, и я нажимаю кнопку «Назад» в контроллере навигации, я обнаруживаю ошибку.
Я проверил с помощью инструментов всю историю изменений счетчика сохранения для моих внутренних контроллеров, и это хорошо (нетнеобычные вещи).Когда возникает ошибка, моя последняя запись в истории происходит из QuartzCore run_animation_callbacks со счетом сохранения -1.
Есть идеи?:)
PS: В качестве быстрого решения для запуска проекта я переместил cancelRequestsForController в отдельный метод и вручную вызываю его для каждого объекта в tableControllers перед выпуском.Таким образом, я уверен, что после выпуска не будет звонков, независимо от состояния таблицы.
- (void)dealloc
{
for (TableController* c in tableControllers)
[c cancelRequests];
SAFE_DEL(tableControllers);
[super dealloc];
}
Но мне не нравится это решение по нескольким причинам.