UIButton исправляет IBAction, вызывая EXC_BAD_ACCESS с ARC - PullRequest
4 голосов
/ 02 февраля 2012

В StackOverflow было несколько вопросов, где пользователи столкнулись с той же проблемой, что и я. Однако ни одно из их решений не подходит под мой случай. (См. здесь , здесь , здесь и здесь для некоторых вопросов SO, которые я прочитал, но не нашел полезным.)

В моем случае у меня есть NIB, у которого есть пара UIButton с ассоциированным видом контроллера. Представление является относительно старым для моего проекта, и я смог использовать эти кнопки без каких-либо проблем до сегодняшнего дня. После внесения нескольких изменений кода, которые не были связаны с поведением кнопки, я столкнулся с ошибкой, которая вылетает из приложения, нарушает код функции main() и выдает мне сообщение об ошибке EXC_BAD_ACCESS всякий раз, когда я касаюсь любые кнопок на моем View.

Как или почему это могло произойти? Я фактически закомментировал почти весь функциональный код, особенно тот, который я изменил ранее сегодня, и я до сих пор не могу остановить возникновение ошибки.

В моем проекте используется автоматический подсчет ссылок, и я не видел эту ошибку раньше. Кроме того, я не модифицировал ни NIB, ни IBAction, связанные с кнопками, поэтому я не вижу, что может вызвать это. Единственный способ устранить ошибку - отсоединить мои UIButton s в моем NIB с IBAction методами, определенными в моем заголовочном файле Controller View.

Единственный «уникальный» аспект моего сценария использования состоит в том, что я загружаю один или два экземпляра этого представления в другой контроллер вспомогательного представления. Количество загруженных экземпляров поврежденного представления зависит от количества объектов в массиве. Ниже приведен код, который я использую для создания экземпляров и загрузки этих представлений как подпредставлений другого представления.

//Called else where, this starts the process by creating a view that 
//will load the problematic view as a sub-view either once or twice.
- (id)initWithPrimarySystemView:(SystemViewController *)svc
{
    //First we create our parent, container view.
    self = [super initWithNibName:@"ContainerForViewInstaniatedFromArrayObjs" bundle:nil];
    if (self) 
    {
        //Assign parent DataModel to local instance
        [self setDataModel:((DataModelClass*)svc.DataModel)];
        for (AnotherModel* d in DataModel.ArrayOfAnotherModels)
        {
            //Instantiate the SubViewController.
            SubViewController* subsvc = [[SubViewController alloc] 
                                            initWithNibName:@"Subview" 
                                          bundle:nil 
                                          subviewPosition:d.Position ];

            //Add the SubViewControllers view to this view.
            [subsvc.view setFrame:CGRectMake((d.Position-1)*315, 0, 315, 400)];
            [self.view addSubview:subsvc.view];
        }
        [self setDefaultFrame: CGRectMake(0, 0, 640, 400)];
    }
    return self;
}

Это работает отлично и раньше даже не вызывало никаких проблем с кнопками, которые были в связанном представлении, однако теперь все UIButton сбои приложения при нажатии.

Функция инициализации для SubViewController, а также метод viewDidLoad не содержат ничего, кроме стандартного автоматически генерируемого кода, который добавляется при создании нового ViewController.

Что я могу сделать, чтобы исправить или диагностировать эту проблему?

Ответы [ 2 ]

8 голосов
/ 02 февраля 2012

Смотрите мои комментарии в вашем коде:

{
    SubViewController* subsvc = [[SubViewController alloc] initWithNibName:@"Subview" bundle:nil subviewPosition:d.Position ];
    //!i: By default, subsvc is a __strong pointer, so your subview has a +1 retain count
    //    subsvc owns subsvc.view, so subsvc.view has a +1 retain count as well

    //Add the SubViewControllers view to this view.
    [subsvc.view setFrame:CGRectMake((d.Position-1)*315, 0, 315, 400)];

    [self.view addSubview:subsvc.view];
    //!i: This bumps subsvc.view to +2, as self.view strong-references it

    //!i: subsvc is going out of scope, so the reference count on subsvc will drop
    //    to 0 and it is dealloc'd.  subsvc.view's retain count drops to +1, as it
    //    is still referenced by self.view
    //
    //    Most likely, in -[SubViewController dealloc], you were not doing a 
    //    setTarget:nil, setAction:nil on the button.  Thus, the button now 
    //    has a dangling pointer and will crash when hit
}

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

1 голос
/ 20 февраля 2012

Удостоверьтесь, что в вашем dealloc вы звоните:

[кнопка удалить цель: ноль Действие: NULL forControlEvents: UIControlEventAllEvents];

Даже если вы не нуждались в "dealloc's" в ARC, вы делаете это из-за того, что объяснил iccir.

...