2014-02-22 46 views
0

每當我的應用程序變得更復雜一些時,它就會盡可能快地達到視圖無法刷新的程度。例如,如果我有播放器按鈕,並且每當用戶點擊該按鈕時,該按鈕將會改變其圖像,然後播放器將播放一些音樂,圖像需要很長時間才能改變。多線程和一般層次理解

無論圖像改變後是否存在「SetNeedsdisplay」,或者即使用戶使用「preformSelectorOnMainThred」進行圖像更改,都會發生這種情況。

我添加的代碼卡,顯示我的意思:

- (IBAction)playButtonPressed:(id)sender { 


//This is the image change, plus a small animation that should happen: 
dispatch_async(dispatch_get_main_queue(), ^{ 

    [self.playButtonImage setImage:[UIImage imageNamed:@"PlayDiscButtonPressedMC"]]; 
    [[self superview] setNeedsDisplay]; 

    [self performSelector:@selector(animationInsertDisk) withObject:nil]; 

}); 

//This is the methus that will call the player to start playing, by delegate. 
[self performSelector:@selector(callDelegate) withObject:nil];; 


} 

發生的是,圖像的變化和動畫約需1-2秒,在它發生之前,因爲「callDelegate」那的之後是!可以說我刪除了「callDelegate」,那麼圖像和動畫將發生海峽離開!

我不明白爲什麼會發生這種情況,不應該首先發生的代碼發生嗎? 在主線程上發生的不夠嗎?

這裏的任何幫助將非常感謝! 謝謝!

回答

0

我將試圖解釋在不久的將來塊

dispatch_async安排一切。例如,如果在按鈕點擊處理程序中調用dispatch_async,則該代碼將不會執行,直到該方法結束並且控件返回給系統。

[self performSelector:@selector(callDelegate) withObject:nil]; 

是一樣的書寫

[self callDelegate]; 

這是一個簡單的方法調用。這是一個阻止電話。如果調用需要一些時間,那麼UI中的所有內容都必須等待(因爲您從UI線程調用它)。

你的代碼是基本相同,以下:

- (IBAction)playButtonPressed:(id)sender { 

    [self callDelegate]; 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self.playButtonImage setImage:[UIImage imageNamed:@"PlayDiscButtonPressedMC"]]; 

     //no need for this here. Don't try to fix bugs by adding random code. 
     //[[self superview] setNeedsDisplay]; 

     //performSelector just calls the method, so a direct call is exactly the same 
     [self animationInsertDisk]; 
    }); 
} 

現在,我不知道你想通過dispatch_async達到的目標。你希望動畫立即開始,你已經在主線程,所以才這樣做的,你是從主線程開始您的播放器和阻斷的事實

- (IBAction)playButtonPressed:(id)sender { 
    [self.playButtonImage setImage:[UIImage imageNamed:@"PlayDiscButtonPressedMC"]]; 
    [self animationInsertDisk]; 

    [self callDelegate]; 
} 

然而,「滯後」可能是造成主線程一段時間。我不確定你在[self callDelegate]中究竟做了什麼,但是通過dispatch_async包裝此呼叫可能有所幫助。

+0

謝謝!這非常有幫助!代碼現在運行得更好。有沒有理由學習多線程或dispatch_async總是答案? – MCMatan

+0

dispatch_async *是*多線程。這只是實現它的衆多方法之一。 –

+0

@Catfish_Man如果你在主線程上並且你在主線程上安排了某些東西,那麼它實際上並不是多線程。 – Sulthan