0

恐怕再多的谷歌搜索都无法挽救我的海德。每当我在任何 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 上,而是发生在我堆栈中的所有 UIView 上。不过,我可以总结一下显示逻辑,也许这会有所启发。

因此创建了应用程序并分配了一个 UIWindow。然后分配一个单独的 viewcontroller,创建并添加它自己的空白 self.view,代表不同游戏状态的其他 UIViews 附加到它上面。

有趣的是,这个错误不会在模拟器上发生,而是在设备上持续发生。而且我还应该提到,该应用程序尚未覆盖/使用任何 touchesBegan:/Ended:/Moved: 等...换句话说,如果代码中没有这些方法,就会发生此错误。

我真的不明白这个错误来自哪里......有什么建议吗?

编辑请求的代码 是一个简化的状态,仍然会在触摸时生成 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

4

3 回答 3

1

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

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

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

(为什么解释性删除有一个单例视图?这是一种单例滥用,在某些商店中禁止使用单例。)

“游戏状态”也不应该在视图或视图控制器中,而是应该驻留在其自己的自定义数据模型对象中。

您看到的问题是为什么首先使用 MVC。通过在视图中塞入如此多的逻辑,您只需触摸界面即可引发不可预知的级联错误。如果您的设计更加模块化,功能明确分离,您将自动知道这个问题来自哪里。

于 2010-04-23T16:47:05.810 回答
0

第一个想法:_exclusiveTouchView 是 UIWindow 的成员变量,看起来设备在其视图层次结构中没有 UIWindow,更具体地说是它的响应者链。确保确实分配了 Window 并且是视图层次结构的顶级视图。您是在使用 Interface Builder 还是自己动手制作?

于 2010-04-23T16:10:44.300 回答
0

好的,问题解决了——似乎主应用程序的单例window变量和游戏状态管理器对window变量的使用之间存在一些名称冲突。正如 TechZen 所提到的,该代码正在尝试将 UIWindow 消息发送到没有该方法的 UIView。 在这里,window主应用程序将其单独用作 UIWindow,windowWPGameState 也将其用作其视口 UIView,从而导致框架内的歧义。

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

于 2010-04-23T18:29:23.983 回答