任何UIView触摸上的SIGABRT

时间:2010-04-23 15:20:08

标签: iphone uiview sigabrt

我担心没有多少谷歌搜索能够拯救我的海德。在任何UIView上触摸屏幕时,我似乎都会收到SIGABRT错误。调试器控制台在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

如果你需要查看UIView的WPGameState子类的一部分,可以在这里找到保存一些帖子的长度:http://tinypaste.com/732bb

3 个答案:

答案 0 :(得分:1)

我认为问题在于您将视图分配给应该拥有窗口的属性。代码试图将UIWindow消息发送给没有该方法的UIView。 (UIWindow是UIView的子类。)

我没有看到直接原因,但他的应用程序显示严重的设计问题。你有一个WPGameState的UIView子类,它本身有一个名为window的UIView属性。这严重破坏了模型 - 视图 - 控制器设计模式。

WPGameStateIntroStateView中的逻辑都不属于视图,逻辑属于视图控制器。您应该有一个视图控制器来管理两个视图并处理它们的显示,计时器等。视图应该只知道如何绘制自己以响应来自视图控制器的命令。

(为什么解释删除的是 单身 视图?这种单身滥用行为导致单身人士禁止在某些商店使用。)

“游戏状态”既不应位于视图控制器中,也不应位于视图控制器中,而应位于其自己的自定义数据模型对象中。

您遇到的问题是为什么首先使用MVC。通过在视图中塞入如此多的逻辑,您可以通过触摸界面来引发不可预测的级联错误。如果您的设计更加模块化,并且功能明确分离,您将自动了解此问题的来源。

答案 1 :(得分:0)

首先想一想:_exclusiveTouchView是UIWindow的成员变量,看来设备在其视图层次结构中没有UIWindow,更具体地说是其响应者链。确保确实正在分配窗口,并且它是视图层次结构的顶级视图。您使用的是Interface Builder还是自己编写?

答案 2 :(得分:0)

好的,问题解决了 - 似乎主应用程序的单例window变量与游戏状态管理器使用window变量之间存在一些名称冲突。正如TechZen所提到的,代码正在尝试将UIWindow消息发送给没有该方法的UIView。这里,window被主应用程序单独用作UIWindow和{{ 1)}也被WPGameState用作其视口,一个UIView,在框架内造成歧义。

第二次使用 window 已重命名为 window ,以解决此问题。