2012-08-17 39 views
0

我有一個賽格瑞,我這樣做:錯誤模擬器爲iPad而不是iPhone

[self performSegueWithIdentifier:@"PlanToBusiness" sender:self]; 

它工作於iPhone,但不是在iPad上。我所做的是遠程調用服務器,當服務器響應正確返回時,我嘗試將用戶帶到具有該segue的新頁面。

它適用於iPhone模擬器,但不是在iPad(識別字符串是兩個相同),並在iPad上也與此錯誤崩潰:

bool _WebTryThreadLock(bool), 0x68f9cb0: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now... 
1 WebThreadLock 
2 -[UITextRangeImpl isEmpty] 
3 -[UITextRange(UITextSelectionAdditions) _isCaret] 
4 -[UITextSelectionView setCaretBlinks:] 
5 -[UIKeyboardImpl setCaretBlinks:] 
6 -[UIKeyboardImpl setDelegate:force:] 
7 -[UIKeyboardImpl setDelegate:] 
8 -[UIPeripheralHost(UIKitInternal) _reloadInputViewsForResponder:] 
9 -[UINavigationController navigationTransitionView:didStartTransition:] 
10 -[UINavigationTransitionView transition:fromView:toView:] 
11 -[UINavigationTransitionView transition:toView:] 
12 -[UINavigationController _startTransition:fromViewController:toViewController:] 
13 -[UINavigationController _startDeferredTransitionIfNeeded] 
14 -[UINavigationController pushViewController:transition:forceImmediate:] 
15 -[UINavigationController pushViewController:animated:] 
16 -[UIStoryboardPushSegue perform] 
17 -[UIStoryboardSegueTemplate perform:] 
18 -[UIViewController performSegueWithIdentifier:sender:] 
19 __41-[PlanBusinessController submitBusiness:]_block_invoke_0 
20 __block_global_0 
21 -[NSBlockOperation main] 
22 -[__NSOperationInternal start] 
23 -[NSOperation start] 
24 __block_global_6 
25 _dispatch_call_block_and_release 
26 _dispatch_worker_thread2 
27 _pthread_wqthread 
28 start_wqthread 

我也不太習慣閱讀O -ctive-C棧跟蹤,所以我很難找出問題所在。

這是我如何做到這一點:

- (IBAction)submitBusiness:(id)sender 
{  
    // Make a url to send 

    NSURL *url = [NSURL URLWithString:full_encoded_url_string]; 
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url]; 

     // *************** 
     // TODO: ok I dont really understand what this is 
     NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 
     // ************** 

     [NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) 
     { 
         // I took out a lot of the logic code that is not needed 

         [self performSegueWithIdentifier:@"PlanToBusiness" sender:self]; 
     }]; 
    } 
} 
+0

你如何處理遠程調用服務器?如果它是一個異步調用,並且您嘗試在調用Web服務而不是主線程的線程中繼續執行,則可能導致此問題。你可能會發布更多的代碼,請求消失的地方以及執行segue的全部函數? – 2012-08-17 16:51:39

+0

@Paul是的,我正在做一個異步調用,並嘗試從返回代碼繼承。什麼是正確的方式來做到這一點,以避免這種錯誤發生? ...現在發佈代碼... – GeekedOut 2012-08-17 16:53:26

+0

@Paul我只是添加了一些我使用的代碼...我拿出了很多錯誤檢查和其他邏輯,但我做的是在那裏。 – GeekedOut 2012-08-17 17:00:24

回答

2

當該觸摸UI方法,例如執行SEGUE時,以確保您所呼叫從主線程的代碼是很重要的。要做到這一點,最簡單的方法就是讓這樣的方法:

- (void)performPlanToBusinessSegueOnMainThread 
{ 
    [self performSegueWithIdentifier:@"PlanToBusiness" sender:self]; 
} 

然後,您可以調用此方法在您的成品塊這樣的:

[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) 
{ 
    // I took out a lot of the logic code that is not needed 

    [self performSelectorOnMainThread:@selector(performPlanToBusinessSegueOnMainThread) 
          withObject:nil 
         waitUntilDone:YES]; 
}]; 

這是一個有點迂迴,但它應該修復你的例外。如果我們可以在performSelectorOnMainThread方法中調用performSegueWithIdentifier會更好,但它有太多的參數。

+0

聰明!我明白你在做什麼。所以我應該把該函數的調用放在從服務器返回的代碼的最後,對吧?這樣我確保這個線程停止運行? – GeekedOut 2012-08-17 17:05:22

+0

只要你將'waituUntilDone'參數設置爲'Yes',你就可以將它放在你想要的任何地方,它將運行得幾乎相同,就好像它不是從一個不同的線程被調用一樣(Except因爲它希望不會拋出異常!)它只是讓web線程等待,直到performSelectorOnMainThread函數返回到下一行。 – 2012-08-17 17:07:35

+0

謝謝! :) 非常感激。 – GeekedOut 2012-08-17 17:09:02

相關問題