EXC_BAD_ACCESS при удалении из супервизии в одноэлементной iOS

#ios #objective-c #exc-bad-access

#iOS #objective-c #исключение-bad-access

Вопрос:

У меня есть синглтон, который подклассирует NSObject. В нем есть ссылка на внутренний просмотр (подкласс UIView), который был добавлен в корневой контроллер представления в качестве подпросмотра. При нажатии определенной кнопки в представлении вызывается метод в singleton, который удаляет представление из его супервизора. Я каждый раз получаю код EXC_BAD_ACCESS = 2. Я понятия не имею, почему, и я пытался использовать zombies и проверять, равна ли ссылка нулю. Я пытался сохранить его, все (все это с использованием ARC). Вот несколько фрагментов кода:

 //the property in the Manager.h file
@property (nonatomic, retain) IntroView *introView;

//Code called when that button is clicked and view is supposed to be removed
- (void)setOption:(NSString *)chosenOption {
    self.chosenOption = chosenOption;
    if (!!self.introView) {
        [self.introView removeFromSuperview]; //THIS LINE
}

//creates the singleton
  (instancetype)manager {
    static Manager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(amp;onceToken, ^{
        manager = [[self alloc] init];
    });
    return manager;
}
  

Приветствуются любые идеи!

Я понял это. Произошел цикл ссылок, который привел к сбою приложения.

Комментарии:

1. Что if (!!self.introView) { предполагается сделать?

2. The !! это обычная идиома для изменения объекта на значение BOOL

3. Как добавляется внутренний просмотр? Как выглядит трассировка стека при сбое?

4. Никогда не видел этого раньше.. В любом случае, какое логическое значение здесь ожидается, true или false? Содержит ли свойство self.introView ссылку на представление, которое вы хотите удалить, и является ли IntroView подклассом UIView? Что, если вы измените атрибут сохранения на слабый?

5. Вау .. Глядя на стек, кажется, что эта строка кода выполняется примерно 50 раз… Я только что взглянул на метод, который вызывает этот метод из IntroView (подкласс UIView), и он вызывается только один раз.. Не совсем уверен, как это могло произойти. Может ли это иметь какое-то отношение к тому факту, что Manager является одноэлементным?

Ответ №1:

Был ссылочный цикл. У меня была функция:

 - (UIView *)introView
  

это ссылалось на себя снова и снова.