2009-11-08 128 views
5

我有一種情況,我懶加載從www的圖像。
這是一個項目列表,當一個項目被點擊時,一個詳細視圖被推送到導航控制器。Cocoa-Touch:performSelectorOnMainThread:奇怪的行爲+崩潰

在該詳細信息視圖中,該項目具有圖像,首先是默認圖像,我想從網址開始加載圖像。

所以我要做的就是創造出初始化一次分離一個新的線程這反過來加載內容和事後通知我認爲該數據被加載的對象:

// in MyLoader: 
- (MyLoader *)initWithUrl:(NSURL *)url requester:(id)requester { 
    self.url = url; 
    self.requester = requester; // both are nonatomic, retain properties 
    [self performSelectorInBackground:@selector(loadIt) withObject:nil]; 
} 

- (void)loadIt { 
    NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init]; 
    NSData *data = [NSData dataWithContentsOfURL:url]; 
    [requester performSelectorOnMainThread:@selector(dataReady) withObject:data waitUntilDone:YES; 
    [arp release]; 
} 

// in MyRequester: 
- (void)somewhere { 
    MyLoader *loader = [[[MyLoader] alloc] initWithUrl:someUrl requester:self] autorelease]; 
    // then I retain loader somewhere, it's more complicated but I have verified that it's properly retained. 
} 

的幾個注意事項:

  1. 首先我認爲可能有一些變量的問題。我在performSelectorOnMainThread之前設置了一個斷點,並確認datarequester都正常。

  2. 然後,我認爲這是由NSData跨線程引起的,所以我改變了withObject:nil。它仍然崩潰。

  3. 當我進一步調查時,撞車事件很奇怪。我指定waitUntilDone:YES,我在requesterdataReady中放置了一個斷點。但performSelectorOnMainThread調用返回(它到達它後面的斷點),但未達到dataReady內的斷點。順便說一句,- (void)dataReady:(NSData*)的身體現在只包含int x = 1;(放置一個斷點)。另外,我試過設置waitUntilDone:NO,它仍然崩潰。

  4. 未執行選擇器(未達到斷點),但在調用後不久發生崩潰。

有沒有人知道有什麼問題?

這是顯而易見的,但只是要清楚,如果我只是註釋掉[requester performSelectorOnMainThread...部分,它不會崩潰。

此外,這是一個堆棧跟蹤,但它根本沒有幫助。

#0 0x00a71004 in ___TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION___() 
#1 0x93436e3b in objc_exception_throw() 
#2 0x0028aca6 in __NSThreadPerformPerform() 
#3 0x00a098e1 in CFRunLoopRunSpecific() 
#4 0x00a08c48 in CFRunLoopRunInMode() 
#5 0x0005a78d in GSEventRunModal() 
#6 0x0005a852 in GSEventRun() 
#7 0x0168a003 in UIApplicationMain() 
#8 0x000028d4 in main (argc=1, argv=0xbffff100) at /Users/myName/Document/appName/main.m:14 
+1

我懷疑有更簡單的方法來查看未捕獲的異常,但嘗試包裝int retVal = UIApplicationMain(argc,argv,nil,nil);在您的main.m文件中使用try/catch塊並檢查或打印出異常。可能會提供一些線索。我知道我可以在這樣的事情之後繼續點擊(在調試器中),並最終打印原因。但這可能是由於我的.gdbinit文件中的一些設置。我的。gdbinit有NSException的一些斷點... – wkw 2009-11-09 00:07:22

回答

9

您有:

[requester performSelectorOnMainThread:@selector(dataReady) withObject:data waitUntilDone:YES; 

應該是:

[requester performSelectorOnMainThread:@selector(dataReady:) withObject:data waitUntilDone:YES; 

通知:@selector(dataReady :)(結腸癌) 既然你傳遞一個參數該方法假定數據就緒定義如下:

- (void) dataReady:(NSData *)theData ... 
+1

缺少冒號,而不是分號。冒號是方法名稱的一部分。 – NSResponder 2009-11-09 04:27:50

+11

未來,您可以通過轉到您的構建設置並在其他警告標誌中添加-Wundeclared-selector來捕獲此信息。這將導致在上述情況下引發警告,其中選擇器不匹配任何已知的方法。 – 2009-11-09 18:37:45