EXC_BAD_ACCESS при закрытии modalViewController iOS5
Я давно почесал голову, пытаясь решить эту проблему. Я искал Stackru и нашел людей, которые просят что-то похожее на мою проблему, например, этот вопрос и этот вопрос, но ни один из приведенных ответов не помог мне.
Чтобы объяснить проблему подробно:
- Я использовал пример Apple Paging для включения подкачки между контроллерами представления
Иерархия представления выглядит следующим образом: UIWindow -> UIScrollView (MainController) -> UIViewControllers.
Я использую этот код для создания делегата Viewcontroller, содержащего UISCrollview:
if(page == 0) { ContractsViewController *controller = [viewControllers objectAtIndex:page]; if ((NSNull *) controller == [NSNull null]) { controller = [[ContractsViewController alloc] initWithNibName:@"ContractsView" bundle:nil]; controller.delegate = self; [viewControllers replaceObjectAtIndex:page withObject:controller]; [controller release]; } // add the controller's view to the scroll view if (controller.view.superview == nil) { CGRect frame = scrollView.frame; frame.origin.x = frame.size.width * page; frame.origin.y = 0; controller.view.frame = frame; controller.view.tag = 0; [scrollView addSubview:controller.view]; } }
Затем возникает проблема, когда я пытаюсь представить modalviewcontroller из моего ViewController внутри scrollview с использованием делегата. Это работает несколько раз, но затем дает мне EXC_BAD_ACCESS. Я также попытался опубликовать уведомление и создать прослушиватель в MainController, чтобы представить его таким образом, но проблема все еще та же.
При тестировании в iOS 4.3 все работает как шарм, но в iOS5 я получаю проблему.
Я надеюсь, что кто-то может помочь мне избавиться от этой проблемы.
Заранее спасибо.
4 ответа
Для начала спасибо за все ваши ответы! Я наконец нашел решение проблемы.
Как уже упоминалось в моем вопросе, я использовал образец Pagecontrol от Apple в качестве шаблона для своего проекта. Этот шаблон имеет rootViewController, который имеет XIB с окном, содержащим UIScrollview и Pagecontrol.
Проблема произошла, когда я пытался представить ModalView из UIViewController внутри прокрутки. Я хотел использовать делегата, чтобы представить его через rootViewController, но обнаружил, что он использует UIScrollview для его представления.
Объект UIScrollView временно не был сохранен, поэтому после нескольких увольнений я нажал EXC_BAD_ACCESS.
Затем я понял, что мне нужен UIView в rootViewController, и разместил его в нижней иерархии в XIB, и соединил его с представлением rootViewController. После того, как я это сделал, я мог использовать [делегат присутствовать..] и [делегат отклонить..] в UIViewController без EXC_BAD_ACCESS.
Ура!:)
Я думаю, что вижу вашу проблему.. во первых, если вы отпустите controller
объект, а затем вы пытаетесь использовать его во втором цикле if, из-за которого вы получаете это. освободить объект контроллера после прохождения обоих циклов if.
РЕДАКТИРОВАТЬ:
попробуйте этот код вместо..
if(page == 0)
{
ContractsViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *) controller == [NSNull null])
{
controller = [[[ContractsViewController alloc] initWithNibName:@"ContractsView" bundle:nil]autorelease];
controller.delegate = self;
[viewControllers replaceObjectAtIndex:page withObject:controller];
}
// add the controller's view to the scroll view
if (controller.view.superview == nil)
{
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
controller.view.tag = 0;
[scrollView addSubview:controller.view];
}
}
Я предлагаю удалить ваш [controller release];
и добавление авто-релиза: controller = [[[ContractsViewController alloc] initWithNibName:@"ContractsView" bundle:nil] autorelease];
Вы не владеете controller
когда он вернется из objectAtIndex:
Таким образом, вы могли бы иметь одинаковое поведение для обоих контроллеров, без выпусков.
Попробуйте запустить код с NSZombiesEnabled.
Я предполагаю, что объект viewControllers либо никогда не инициализируется, либо освобождается преждевременно.
Кроме того, есть это if (page == 0)
wierdness:
if(page == 0) // <== only the first page ever gets the init code calling
{
ContractsViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *) controller == [NSNull null])
{
// ** SNIP **
[viewControllers replaceObjectAtIndex:page // <<=== always 0
withObject:controller];
[controller release];
}
// ** SNIP **
}