2010-04-23 43 views
1

恐怕沒有任何數量的谷歌搜索已經能夠保存我的海德了。我在任何時候在任何UIView上觸摸手機的屏幕時,似乎都會收到SIGABRT錯誤。調試器控制檯的帖子這個錯誤的SIGABRT前:SIGABRT在任何UIView觸摸上

.... [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:等等......換言之,在代碼中發生這種錯誤而沒有這些方法。

我真的不知道這個錯誤來自哪裏......任何建議?

EDIT這裏請求碼是仍然生成觸摸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

+0

請提供重現問題的最簡單的UIView子類代碼。我們將能夠從那裏提供幫助。 – 2010-04-23 15:24:02

+0

不知道它是否直接相關,但使用單身視圖絕對是單身濫用。意見應該是愚蠢和可互換的。每個視圖應該只有足夠的邏輯來處理其即時顯示需求。他們不應該有關鍵的應用程序邏輯,以便每個應用程序只有一個存在。你需要重新考慮你的設計。 – TechZen 2010-04-23 16:32:59

+0

@TechZen - 在設計方面,這些獨特的視圖負責代表各個遊戲狀態的大部分自己的環境。他們意味着有重要的邏輯,但不是應用邏輯。不過,我同意非遊戲應用程序應該遠離單例視圖。 – bitcruncher 2010-04-23 17:45:03

回答

0

好的,問題解決了 - 似乎主應用程序的單例window變量與遊戲狀態管理器使用window變量之間有一些名稱衝突。正如TechZen提到的那樣,代碼試圖將UIWindow消息發送到沒有方法的UIView。這裏,window由主應用程序作爲一個UIWindow和window單獨使用也正在被WPGameState作爲其視口,一個UIView,框架內引起歧義。

二使用的window已更名爲viewport,解決問題。

0

的第一個想法:_exclusiveTouchView是一個UIWindow的成員變量,它出現該設備的視圖層次結構中沒有UIWindow,更具體地說,它的響應者鏈。確保窗口確實正在分配,並且是視圖層次結構的頂層視圖。您是使用Interface Builder還是自己動手製作?

+0

滾動我自己的。應用程序委託裝載負責接管整個應用程序的單例類。這是其中一個UIWindow被聲明和alloc'd下列方式(窗口是具有保留屬性的類變量): 窗口= [[ALLOC的UIWindow] initWithFrame:方法[[UIScreen mainScreen]界限]]; [window makeKeyAndVisible]; 從此,視圖控制器被加載,使其自身的self.view並將THAT附加到[window addSubview :(單個VC self.view)] – bitcruncher 2010-04-23 16:20:15

+0

UIView \t * window;建立?你可以請張貼你的啓動代碼嗎?這通常是在東西 - (空)的applicationDidFinishLaunching:(UIApplication的*)應用程序... 什麼是viewOutlet初始化? window = [theGame viewOutlet]; ---提示----- 在你的初始化代碼,你調用[超級初始化],然後..initWithFrame(也叫[超級初始化。這是不好的,只是子類(ID)initWithFrame :(CGRect)aRect或不明確地調用[super init] – gnasher 2010-04-23 16:45:10

+0

UIWindow *窗口在遊戲單例標題中被聲明爲一個類變量,它被分配在單例實現文件中,如我上面的註釋中所述。 (+1) – bitcruncher 2010-04-23 22:13:32

1

我認爲問題在於你將某個視圖分配給應該保存一個窗口的屬性。該代碼試圖發送一個UIWindow消息到沒有該方法的UIView。 (UIWindow是UIView的子類。)

我沒有看到直接的原因,但是他的應用程序顯示出嚴重的設計問題。你有一個WPGameState的UIView子類,它本身有一個名爲window的UIView屬性。這嚴重打破了模型 - 視圖 - 控制器的設計模式。

WPGameStateIntroStateView都不屬於視圖,該邏輯屬於視圖控制器。你應該有一個單一的視圖控制器來管理這兩個視圖並處理它們的顯示,定時器等。視圖應該只知道如何繪製自己以響應來自視圖控制器的命令。

(以及爲什麼explicative缺失是有看法呢?這是一種單濫用行爲得到禁止使用在一些商店單身。)

也不應該將「遊戲狀態」是在任何一個視圖或視圖控制器而是應當駐留在其自己的自定義數據模型對象。

那種你看到的問題是,爲什麼MVC是首先使用。通過在視圖中填充如此多的邏輯,只需觸摸界面即可引發不可預知的級聯錯誤。如果您的設計更加模塊化並且功能明確分離,則您可以自動知道問題來自何處。

+0

@TechZen - 好的,我看到你來自哪裏,雖然我不同意。在這裏,我有一個視圖控制器運行爲顯示服務器,而通過單例實現的視圖(個人和獨特的遊戲狀態),根據需要附加到顯示服務器的self.view,這就是爲什麼該類不包含關鍵邏輯,除了設備旋轉和ge neralized視圖管理。在這家商店裏,我們尊重MVC方法的某些任務,但這不是其中之一。然而,我會很樂意在這裏提出你的答案,因爲它確實幫助我找到了實際的錯誤。 – bitcruncher 2010-04-23 18:18:56

+0

我不會告訴您您的業務,但我會建議您將您的設計與API匹配。我可以從你的術語中知道你來自一個強大的C++(或類似的)背景,並且你試圖將這種體驗映射到這個API上。 Objective-C和API足夠靈活,你可以做任何你想做的事情,但是如果你不圍繞一個強大的MVC設計構建,你將會一直與API戰鬥,而不是讓它幫助你。 – TechZen 2010-04-24 13:11:08