SIGABRT on any UIView touch
I'm afraid no amount of Googling has been able to save my hyde on this. I seem to be getting SIGABRT error anytime I touch the screen of the phone, on any UIView. The debugger console posts this error before the 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'
(this is not my specific call to _exclusiveTouchView
, of course.)
I would gladly post some code, but the truth is I cannot find (or guess) where this problem may be coming from. This is not happening on any ONE UIView but on all the UIViews in my stack. I can summarize the display logic, though, perhaps that will shed some light.
So the application is created and a UIWindow is alloc'd. A single viewcontroller is then alloc'd, which makes and adds its own blank self.view, to which the other UIViews, representing the different game states, are attached.
Interestingly enough, this error is does NOT happen on the Simulator, but happens consistently on the device. And I should also mention that the application has yet to override/use any of the touchesBegan:/Ended:/Moved: etc... In other words, this error happens without these methods in the code.
I'm really not understanding where this error is coming from... Any suggestions?
EDIT for requested code here is a simplified state that still generates SIGABRT on touch:
#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];
intr开发者_StackOverflow社区oTimer = [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
and if you need to see parts of the WPGameState subclass of UIView, it can be found here to save some post length: http://tinypaste.com/732bb
I think the problem is that somewhere you assign a view to a property that should hold a window. The code is trying to send a UIWindow message to a UIView which does not have the method. (UIWindow is a subclass of UIView.)
I don't see the immediate cause but this his app shows severe design problems. You have a UIView subclass of WPGameState which itself has a UIView property called window
. This breaks the Model-View-Controller design pattern badly.
None of the logic in either WPGameState
nor IntroStateView
belong in a view, that logic belongs in a view controller. You should have a single view controller that manages both views and handles their display, timers etc. The views should only know how to draw themselves in response to commands from the view controller.
(And why the explicative-deleted is there a singleton view? This is the kind of singleton abuse that gets singletons banned from use in some shops.)
Neither should the "game state" be in either a view or a view controller but instead should reside in its own custom data model object.
The kind of problem you are seeing is why MVC is used in the first place. By cramming so much logic into your views, you can set off an unpredictable cascade of errors just by touching the interface. If your design was more modular with clear separation of function, you would know automatically where this problem was coming from.
First thoughts: _exclusiveTouchView is a member variable of UIWindow, it appears the device does not have a UIWindow in its view hierarchy, more specifically its responder chain. Insure that a Window is indeed being allocated and is the top level view of your view hierarchy. Are you using Interface Builder or rolling your own?
Ok, problem solved -- it seems there was some name clash between the main application's singleton window
variable, and the gamestate manager's use of the window
variable, as well. As TechZen mentioned, The code is trying to send a UIWindow message to a UIView which does not have the method. Here, window
was used separately by the main application as a UIWindow and window
was also being used by WPGameState as its viewport, a UIView, causing ambiguity within the frameworks.
Second use of window
has been renamed to viewport
, resolving the issue.
精彩评论