#iphone #ios #objective-c #ipad #ios4
#iPhone #iOS #objective-c #iPad #ios4
Вопрос:
Я пытаюсь использовать подкласс UIApplication для отслеживания всех событий касания, это используется, чтобы увидеть, является ли пользователь afk или нет. В любом случае, это отлично работает при первом запуске приложения. Если вы переведете его в фоновый режим и откроете снова 2 раза, то произойдет сбой. Я понятия не имею, что является причиной этого. Я получаю EXEC_BAD_ACCESS на [super SendEvent: событие];
Мой подкласс MyUI:
@implementation MyUI
- (void)sendEvent:(UIEvent *)event {
[super sendEvent:event]; // <-- EXEC_BAD_ACCESS
if (event.type == UIEventTypeTouches) {
UITouch *touch = [event allTouches].anyObject;
if (touch.phase == UITouchPhaseBegan) {
// Calling some methods
}
}
}
@end
Main.m
int main(int argc, char *argv[])
{
NSString* appClass = @"MyUI";
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, appClass, nil);
[pool release];
return retVal;
}
Комментарии:
1. можете ли вы добавить трассировку стека? Я использую тот же подход в своем приложении для отслеживания каждого события касания, и это работает нормально.
Ответ №1:
Есть ли причина, по которой метод суперкласса вызывается первым? Если вы перехватываете, вы должны вызывать его последним.
Это может быть вашей проблемой. Я также переопределяю SendEvent для перехвата всех событий в моем приложении и не испытываю проблем.
Если вы сначала вызовете метод super, он передаст его всем UIResponders, которые в конечном итоге могут использовать ваше событие, приводящее к EXEC_BAD_ACCESS. Кроме того, как предлагает ДэвидНейсс, удалите строки под суперзвонком. Если вы все еще получаете сигнал плохого доступа, его, вероятно, вызывает другое представление или контроллер по линии. Вам нужно выполнить трассировку стека, чтобы выяснить, где это находится.
Ответ №2:
Чтобы получить точную причину EXEC_BAD_ACCESS, используйте nszombieenabled в вашем приложении. Эта ссылка поможет вам использовать ее. http://iosdevelopertips.com/debugging/tracking-down-exc_bad_access-errors-with-nszombieenabled.html
Комментарии:
1. Не могли бы вы, пожалуйста, объяснить, где у вас произошла утечка? У меня такая же проблема
2. Точно; если этот ответ помог вам найти проблему, пожалуйста, обновите свой вопрос или добавьте комментарий, объясняющий, в чем была причина / как вы ее решили. Это может помочь другим людям!
Ответ №3:
Не понимаю, что означает «afk».
Другим подходом может быть создание пользовательского средства распознавания жестов. Предполагается, что они (средства распознавания жестов) фильтруют события касания, прежде чем они будут перенаправлены в представление как часть обычной обработки событий касания.
Комментарии:
1. afk означает «вдали от клавиатуры». Другими словами, я проверяю, продолжает ли пользователь использовать ipad / iphone или пользователь отсутствует.
2. Хорошо, итак, класс UIApplication пересылает события в UIWindow. Что, если вместо создания подкласса UIApplication вы создаете подкласс UIWindow и помещаете свою обработку в его метод события — (void)SendEvent:(UIEvent *). Я попробовал это и добавил NSLog () / [super SendEvent: event] в мой и увидел, что выходят события.
3. Кроме того, для того, как вы это делаете, если у вас просто есть строка «[super SendEvent:event]; // <— EXEC_BAD_ACCESS» и избавиться от материала, который вы добавили под ним, произойдет ли сбой? Если это так, то что-то перепутано, потому что на самом деле вам не следует что-то менять с этим. Я бы вернул это изменение и посмотрел, все ли еще происходит сбой.
Ответ №4:
Просто для простоты я бы поместил @»MyUI» непосредственно в вызов UIApplicationMain.
Строка, скорее всего, является вашей проблемой. Это находится за пределами NSAutoreleasePool
, и это просто не выполняется.
Кроме того, имя @»MyUI» указывает на контроллер представления, а не на класс AppDelegate. Посмотрите на это.
Ответ №5:
[super SendEvent: событие]; // <— EXEC_BAD_ACCESS
означает, что ошибка в вашем классе.
Для блока тестирования
/*
- (void)sendEvent:(UIEvent *)event {
[super sendEvent:event]; // <-- EXEC_BAD_ACCESS
if (event.type == UIEventTypeTouches) {
UITouch *touch = [event allTouches].anyObject;
if (touch.phase == UITouchPhaseBegan) {
// Calling some methods
}
}
}
*/
вы все равно получите эту ошибку. В любое время, если вы получаете ошибку при переопределении SendEvent
попробуйте заблокировать все методы переопределения и проверьте, по-прежнему вы получаете эту ошибку или нет специально для этой строки [super sendEvent:event];
. Я также столкнулся с этой ошибкой и не обнаружил ошибки в этом методе. Ошибка была найдена в applicationDidFinishLaunching
. Всегда сохраняйте свой код в методе try catch
@try {
}
@catch (NSException *exception) {
NSLog(@"Exception => %@",exception);
}
Это поможет вам разобраться в правильной проблеме.
Комментарии:
1. Добавление точки останова общего исключения (которая кэширует все исключения в Xcode) является гораздо лучшим решением, чем перенос вашего кода в try catch.