问题 对UIApplication进行子类化以覆盖sendEvent会导致崩溃


我正在尝试子类UIApplication来捕获所有触摸事件,这用于查看用户是否是afk。无论如何,它在您第一次启动应用程序时效果很好。如果你把它放在后台并再次打开2次,那么它会崩溃。我不知道是什么原因引起的。我在[super sendEvent:event]上获得了EXEC_BAD_ACCESS;

我的子类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;
}

9617
2018-05-02 01:57


起源

你可以添加堆栈跟踪吗?我在我的应用程序中使用相同的方法来跟踪每个触摸事件,它工作正常。 - Anurag


答案:


要获得EXEC_BAD_ACCESS的确切原因,请在您的应用程序中使用nszombieenabled。 此链接将指导您使用它。   http://iosdevelopertips.com/debugging/tracking-down-exc_bad_access-errors-with-nszombieenabled.html


4
2018-05-02 05:29



你能解释一下你泄漏的地方吗?我也有同样的问题 - Impossible
究竟;如果这个答案帮助您找到问题,请更新您的问题或添加评论,说明原因是什么/如何解决它。它可能会帮助其他人! - Nicolas Miari


是否有理由首先调用超类方法?如果你正在拦截,你应该最后调用它。

那可能是你的问题。我还覆盖sendEvent来截取我的应用程序的所有事件,没有任何问题。

如果你首先调用super方法,它会将它传递给所有可能最终吃掉你的事件的UIResponder,导致EXEC_BAD_ACCESS。此外,DavidNeiss建议消除超级电话下方的线路。如果您仍然收到错误的访问信号,则可能是另一个视图或控制器导致该错误访问信号。您需要堆栈跟踪以找出它的位置。


4
2018-05-04 06:47





不明白“afk”是什么意思。

另一种方法可能是创建自定义手势识别器。它们(手势识别器)应该在触摸事件被转发到视图之前通过触摸事件进行过滤,作为正常触摸事件处理的一部分。


1
2018-05-02 02:45



afk意味着远离键盘。换句话说,我正在检查用户是否仍在使用ipad / iphone或用户是否离开。 - David
好的,所以UIApplication类将事件转发到UIWindow。如果不是子类化UIApplication,则将UIWindow子类化并将其处理放在其 - (void)sendEvent:(UIEvent *)事件方法中。我已经尝试过并添加了一个NSLog()/ [super sendEvent:event]来挖掘和看到事件。 - DavidN
另外,对于你这样做的方式,如果你只是拥有“[super sendEvent:event]; // < - EXEC_BAD_ACCESS”这一行并摆脱你在它下面添加的东西,它会崩溃吗?如果是这样,那么事情就搞砸了,因为你不应该真的改变它。我会支持这个改变,看看它是否仍在崩溃。 - DavidN


为了简单起见,我会将@“MyUI”直接放入UIApplicationMain调用中。

字符串很可能是你的问题。它在...之外 NSAutoreleasePool,那就是没有完成。

此外,名称@“MyUI”提示视图控制器,而不是AppDelegate类。看看那个。


1
2018-03-14 03:59





[super sendEvent:event]; // < - 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
2017-11-05 09:41



添加一个通用异常断点(缓存Xcode中的所有异常)比在try catch中包装代码要好得多。 - animaonline