EXC_BAD_ACCESS при закрытии modalViewController iOS5

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

Чтобы объяснить проблему подробно:

  1. Я использовал пример Apple Paging для включения подкачки между контроллерами представления
  2. Иерархия представления выглядит следующим образом: 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 **

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