Почему мой сбой и произнесение EXC-BAD_ACCESS при попытке показать GKPeerPickerController(ARC включен)
Недавно я столкнулся с проблемой в приложении, которое я разрабатываю. Приложение аварийно завершает работу с EXC_BAD_ACCESS. Это не имеет смысла, потому что автоматический подсчет ссылок включен.
В приложении у меня есть кнопка, которая связана с IBAction, который отображает GKPeerPickerController.
-(IBAction)showPicker:(id)sender
{
picker = [[GKPeerPickerController alloc ] init];
picker.delegate = self;
picker.connectionTypesMask = GKPeerPickerConnectionTypeNearby;
[picker show];
}
Это не имеет смысла, потому что, если я попытаюсь управлять памятью с помощью вызовов, таких как release, я получу сообщение об ошибке, в котором говорится, что ARC отключает этот вызов. Так что, насколько я знаю, я ничего не могу с этим поделать. Когда происходит сбой, EXC_BAD_ACCESS находится на линии, которая выделяет и инициализирует GKPeerPickerController.
1 ответ
Это происходит только во второй раз, когда вы пытаетесь запустить GKPeerPicker?
EXC_BAD_ACCESS
генерируется, когда ваше приложение пытается получить доступ к области памяти, которой оно не "принадлежит". Это может происходить различными способами, даже с ARC, что затрудняет диагностику.
Проверьте этот вопрос, например, о сбое EXC_BAD_ACCESS (SIGSEGV) - использование NSZombies может быть способом отследить, что происходит.
Однако, немного больше понимания того, что происходит, может помочь вам понять этот сбой и исправить его.
Первый вопрос - как можно получить EXC_BAD_ACCESS, когда мы просто присваиваем недавно выделенный объект? Ну, вот тут-то и начинается волшебство ARC... Этот простой оператор присваивания назначает новый объект переменной экземпляра. Компилятор увидит это и скажет: "Ах... что у ivar уже может быть назначенный объект, и в этом случае я бы лучше выпустил его... Поэтому он добавит некоторый код для проверки nil
и отпустите ivar, прежде чем он назначит новое значение.
Итак, я считаю маловероятным, что alloc / init вызывает вашу проблему, и более вероятно, что это то, что в данный момент хранится в вашем picker
ivar... Что произойдет, если вы сделаете picker
локальная переменная вместо ивара?
-(IBAction)showPicker:(id)sender
{
GKPeerPickerController *localPicker = [[GKPeerPickerController alloc ] init];
localPicker.delegate = self;
localPicker.connectionTypesMask = GKPeerPickerConnectionTypeNearby;
[localPicker show];
}