SIGABRT на любом прикосновении UIView - PullRequest
1 голос
/ 23 апреля 2010

Боюсь, никакое количество Google не смогло спасти мой хайд на этом.Кажется, я получаю ошибку SIGABRT каждый раз, когда я касаюсь экрана телефона, на любом UIView.Консоль отладчика отправляет эту ошибку перед SIGABRT:

.... [310:207] *** -[UIView _exclusiveTouchView]: unrecognized selector sent to instance 0x14c0c0
.... [310:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UIView _exclusiveTouchView]: unrecognized selector sent to instance 0x14c0c0'

(это, конечно, не мой конкретный вызов _exclusiveTouchView)

Я с удовольствием выложу некоторый код, ноПравда в том, что я не могу найти (или догадаться), откуда может возникнуть эта проблема.Это не происходит ни на одном одном UIView, но на всех UIViews в моем стеке.Я могу суммировать логику отображения, хотя, возможно, это будет пролить некоторый свет.

Итак, приложение создано и UIWindow выделено.Затем выделяется один viewcontroller, который создает и добавляет свой собственный пустой self.view, к которому присоединяются другие UIViews, представляющие различные игровые состояния.

Интересно, что эта ошибка НЕ ​​происходитна симуляторе, но происходит последовательно на устройстве.И я должен также упомянуть, что приложению еще предстоит переопределить / использовать любой из touchesBegan: / Ended: / Moved: etc ... Другими словами, эта ошибка происходит без этих методов в коде.

Я действительно не понимаю, откуда возникает эта ошибка ... Есть предложения?

РЕДАКТИРОВАТЬ для запрошенного кода Вот упрощенное состояние, которое все еще генерирует SIGABRT нанажмите:

#import <UIKit/UIKit.h>

#import "WPGame.h"
@class WPGame;
extern WPGame *theGame;

#import "WPGameState.h"

@class IntroView;

@interface IntroStateView : WPGameState {
    NSTimer         *introTimer;
}
+(IntroStateView*)instance;
@end

.

#import "IntroStateView.h"
#import "StartMenuStateView.h"
static IntroStateView *theOnlyIntro = nil;

@implementation IntroStateView

+(IntroStateView*)instance {
    @synchronized(self) {
        if (!theOnlyIntro) {
            theOnlyIntro = [[IntroStateView alloc] init];
        }
    }
    return theOnlyIntro;
}

- (void)excuseYourself {
    [self changeStateOf:theGame toState:[StartMenuStateView instance]];

}

- (void)startUp {
    [super startUp];

    introTimer = [NSTimer scheduledTimerWithTimeInterval:[theGame introLength]
                            target:self
                                selector:@selector(excuseYourself)
                                userInfo:NULL
                                 repeats:NO];
}

- (void)cleanUp {
    [super cleanUp];
}

- (void)handleEvents:(WPGame*)game {
    [super handleEvents:game];
}

- (void)dealloc {
    theOnlyIntro = nil;
    [super dealloc];
}

@end

, и если вам нужно увидеть части подкласса WPGameState в UIView, его можно найти здесь, чтобы сохранить некоторую длину сообщения: http://tinypaste.com/732bb

Ответы [ 3 ]

1 голос
/ 23 апреля 2010

Я думаю, что проблема в том, что где-то вы назначаете представление свойству, которое должно содержать окно.Код пытается отправить сообщение UIWindow в UIView, у которого нет метода.(UIWindow является подклассом UIView.)

Я не вижу непосредственной причины, но это его приложение показывает серьезные проблемы дизайна.У вас есть подкласс UIView WPGameState, который сам имеет свойство UIView с именем window.Это сильно нарушает шаблон проектирования Model-View-Controller.

Ни логика ни в WPGameState, ни IntroStateView не принадлежит представлению, эта логика принадлежит контроллеру представления.У вас должен быть один контроллер представления, который управляет как представлениями, так и их отображением, таймерами и т. Д. Представления должны знать, как рисовать себя только в ответ на команды от контроллера представления.

(И почему объяснение-удалено есть представление singleton ? Это тот тип злоупотребления одиночкой, который запрещает использование синглетонов в некоторых магазинах.)

«Игровое состояние» также не должно быть ни в виде, ни в контроллере вида, а должно находиться в собственном объекте модели данных.

Проблема, которую вы видите, заключается в том, почему MVC используется в первую очередь.Вбив столько логики в свои представления, вы можете вызвать непредсказуемый каскад ошибок, просто прикоснувшись к интерфейсу.Если бы ваш дизайн был более модульным с четким разделением функций, вы бы автоматически знали, откуда возникла эта проблема.

0 голосов
/ 23 апреля 2010

Хорошо, проблема решена - кажется, что произошло некоторое столкновение имен между одноэлементной переменной window основного приложения и использованием менеджером состояния игры переменной window. Как упомянул TechZen, Код пытается отправить сообщение UIWindow в UIView, у которого нет метода. Здесь window использовалось основным приложением отдельно как UIWindow, а window также используется WPGameState в качестве области просмотра, UIView, вызывая неоднозначность в рамках.

Второе использование window было переименовано в viewport, что решило проблему.

0 голосов
/ 23 апреля 2010

Первые мысли: _exclusiveTouchView является переменной-членом UIWindow, кажется, что устройство не имеет UIWindow в своей иерархии представлений, точнее, в цепочке респондентов. Убедитесь, что окно действительно выделено и является видом верхнего уровня иерархии вашего представления. Используете ли вы Interface Builder или используете свой собственный?

...