2012-06-01 98 views
1

我有以下問題: 我希望用戶按下按鈕時進行下載。在此下載過程中,我想隱藏其他按鈕(這會打開下載的文件,所以我想確保在更新尚未完成時沒有人嘗試打開文件)。 在這個過程中可以隱藏這些按鈕嗎?Objective C中更新過程中是否可以隱藏按鈕?

所以我曾嘗試和迄今爲止經歷:

  • 更改按鈕我得到的永遠只是在最後(當它不再是必需的,因爲那時的更新完成)。

我嘗試以下(僞):

-(void)updatingprogress 
{ 
    buttona.hidden=TRUE; 
} 

-(void)updatingfinished 
{ 
    buttona.hidden=FALSE; 
} 

updateFiles() 
{ 
[self updatingprogress] 
... make downloads... 
[self updatingfinished] 
} 

因此,與記錄我看到的,我在我在我想此刻的功能得到,但按鍵的變化過程中都沒有做「updatingprogress」。任何想法如何解決這個問題? 謝謝,最好的問候!

+0

謝謝您的回答!在主線程上工作的想法解決了我的問題。 – Fringer

回答

1

另一種可能性是您正在主線程中執行所有工作,但未能考慮到這樣的事實:在下拉到runloop之前,UIKit更改不會生效。

後臺邏輯是您不希望部分更改可見,例如,如果你寫道:

// okay, set to success 
label.textColor = [UIColor greenColor]; // was previously red 
label.text = @"Success";     // previously said 'Failure' 

什麼您明確不希望是單詞「失敗」以顯示爲綠色,則字更改爲「成功」。你想讓這兩個改變以原子方式發生。 Apple通過將UIKit更新批處理到一起並在任何預定方法之外影響它們來實現此目的。

所以,如果你在主線程上有一些功能來做一些用戶界面的改變,做一些工作,然後撤銷用戶界面的改變,但是沒有任何一點退出到運行環境,那麼改變將永遠不會被看到。

最快的解決辦法是:

- (void)updateFiles 
{ 
    [self updatingProgress]; 
    [self performSelector:@selector(doFileUpdate) withObject:nil afterDelay:0.0]; 

    // what does the above achieve? It schedules doFileUpdate on the runloop, to 
    // occur as soon as possible, but doesn't branch into it now. So when this 
    // method returns UIKit will update your display 
} 

- (void)doFileUpdate 
{ 
    /* heavy lifting here */ 
    [self updatingFinished]; 
} 
4

一個常見問題是您正在嘗試更新後臺線程上的UI元素。如果您的updateFiles方法發生在另一個線程上,您的按鈕可能無法正確隱藏。要將方法派發到主線程,您可以使用API​​或GCD API。

NSOperationQueue:

[[NSOperationQueue mainQueue] addBlockOperation:^ { 
    buttona.hidden = YES; 
}]; 

GCD:

dispatch_async(dispatch_get_main_queue(),^{ 
    buttona.hidden = YES; 
}); 

兩種這些API做同樣的事情。我通常嘗試使用highest abstraction possible,因此在這種情況下,我會使用NSOperationQueue方法

+0

這是個好建議。用於大致相同目的的另一種選擇是NSObject方法'-performSelector:onMainThread:waitUntilDone:' –

相關問題