2011-06-03 115 views
7

在我的iOS應用程序中,我執行以下操作。異步函數執行?

viewDidAppear(){ 

    // Load a spinner in a view on the top 
    [DSBezelActivityView newActivityViewForView:self.view]; 
    // Execute code that require 3 seconds 
    ... 
    // Stop the spinner 
    [DSBezelActivityView removeViewAnimated:YES]; 
} 

問題是,微調不出現,因爲CPU正在努力(類似的東西)。這就像開始和停止之間的代碼優先於視圖的渲染。

我很想找到一種方法來有效地顯示微調開始,而不使用計時器來延遲代碼執行。啓動和停止活動的指標成單獨的線程,因爲它的阻止主線程之間

感謝

回答

22

如果你有一個像

-(void) showSpinner:(UIView*)view { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [DSBezelActivityView newActivityViewForView:view]; 
    }); 
} 

有幾種方法可以從不同的線程中調用它的方法。從下面選擇一個:

[NSThread detachNewThreadSelector:@selector(showSpinner:) toTarget:self withObject:self.view]; 
// or 
[self performSelectorInBackground:@selector(showSpinner:) withObject:self.view]; 
// or 
NSInvocationOperation *invOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(showSpinner:) object:self.view]; 
NSOperationQueue *opQueue = [[NSOperationQueue alloc] init]; 
[opQueue addOperation:invOperation]; 
// or 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    [self showSpinner:self.view]; 
}); 

Alt + click for details。

+1

這對我有效!最後一個選項是最好的,因爲我不需要創建一個函數來創建一個更復雜的函數。 TNX! ;) – jollyr0ger 2011-06-03 12:51:26

+0

前3個選項正在更新後臺線程的UI ... – TheBlack 2011-06-03 16:26:10

+0

@Jano感謝了很多偉大的工作。 – 2013-07-19 07:02:32

1

移動代碼。這就是爲什麼沒有顯示活動指標。

編輯:Example

+1

沒想到從任何的UIKit應該從另一個線程調用還是我錯了?謝謝 – theiOSDude 2011-06-03 10:01:34

+0

如果可能的話,我怎樣才能在另一個線程中調用該代碼? – jollyr0ger 2011-06-03 10:44:18

+0

查看nsinvocation多數民衆贊成在當我開始傾斜它.. GCD是一個替代,但國際海事組織並不那麼好 - http://www.icodeblog.com/2010/03/04/iphone-coding-turbo-charging-your- apps-with-nsoperation/ – theiOSDude 2011-06-03 10:45:26

0

我同意第一個答案和幾個修改。我剛剛經歷了這個完全相同的問題。問題在於,如果有代碼需要時間來完成,任何圖形將自動移動到後臺更新。無論如何,將微調投入背景是它無論如何要做的。你想要的是(可悲的是)你的主代碼在後臺運行,微調器在前臺運行。我知道這聽起來很糟糕,但在某些情況下,允許您的代碼運行速度稍慢,以表明應用程序正在執行某些有用的操作對用戶有益。

爲了得到微調工作: 1)採取一切,是以3秒運行代碼,並將它放入一個函數,它是一個void函數 2)實例化微調,但其存儲到可在viewDidAppear例程之外訪問的變量。 3)啓動一個新的NSTimer,它會以大約每四分之一秒的增量連續運行。我將定義在每個週期稍後調用的例程中。 4)使用performSelectorInBackground功能調用您在步驟1中創建的例程。這基本上是現在將在背景中運行你的啓動(3秒的價值),這是真正讓動畫微調器顯示真正動畫的唯一方法。 5)在第1步中創建的例程中,在頂部添加一行代碼,將代碼(全局對象)布爾值更新爲true,表明我們處於主要3秒例程的中間。 6)在步驟1中定義的例程結束時,添加一行代碼,將在步驟5中定義的同一全局設置爲false,表示我們的3秒例程已完成。 7)在定時程序,我們現在想要做的東西,看起來像下面這樣:

// If busy that start the spinner 
if(YES == busy){ 
    [spinner startAnimating]; 
}else{ 
    [spinner stopAnimating]; 

    // Here we can also stop and deallocate the timer 
} 

如果您需要在這個問題上提供更多的援助,我的確可以提供準確的代碼。看看我爲Pepperdine News Group開發的示例應用程序。當你按下按鈕時,微調器出現在屏幕的右上角。

http://itunes.apple.com/us/app/pepperdine-graphic-for-iphone/id516343215?mt=8