2015-08-17 52 views
0

我對Swift編程語言,製作圖形用戶界面以及通常使用異步調度相當陌生,因此請原諒這個我想象得到的問題有一個令人難以忍受的簡單答案。Swift中的異步調度資源豬

我試圖做的是根據是否選擇有效設置,禁用並重新啓用GUI中的Next按鈕。這些設置可在兩個複選框和一個文本字段中找到。

我的想法是在後臺持續檢查設置,如果有效,啓用Next按鈕。此代碼塊是我最近的嘗試:

func checkValidSettings() { 
    let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT 
    dispatch_async(dispatch_get_global_queue(priority, 0)) { 
     while true { 
      if self.textField.stringValue == "Test" { 
       dispatch_async(dispatch_get_main_queue()) { 
        self.nextButton.enabled = false 
       } 
      } else if (self.checkBox1.state == NSOffState && self.checkBox2.state == NSOffState){ 
       dispatch_async(dispatch_get_main_queue()) { 
        self.nextButton.enabled = false 
       } 
      } else { 
       dispatch_async(dispatch_get_main_queue()) { 
        self.nextButton.enabled = true 
       } 
      } 
     } 
    } 
} 

雖然這可以正常運行,它會導致應用程序是一個巨大的資源豬(100%的CPU和內存的幾個GB),我以爲是因爲一噸的後臺任務正在創建。我弄得很糟糕,哈哈。

我的問題是:我應該如何構建while循環,以便它不斷檢查設置,同時不佔用我所有的資源?還是有更簡單的GUI管理方法?

在此先感謝您的任何建議或幫助您可以給!

+1

爲什麼循環?只要檢查價值變化的條件。你可以爲它註冊回調。你的代碼也不是線程安全的。您無法從非主線程訪問UI元素。 –

+0

你知道,這比我想要做的更有意義,哈哈。如何檢查價值變化時的條件? – humcat

+0

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSTextField_Class/#//apple_ref/occ/instm/NSTextField/textDidChange: –

回答

2

在iOS中,您不必創建自己的偵聽器。你可以簡單地分配一個IBAction和一些布爾。

@IBOutlet weak var field1: UITextField! 
@IBOutlet weak var field2: UITextField! 

var fieldCheck1: Bool = false 
var fieldCheck2: Bool = false 

@IBAction func field1Changed(sender: AnyObject) { 
    if field1.text == "true statement" { 
     fieldCheck1 = true 
    } 
    self.checkComplete() 
} 


@IBAction func field2Changed(sender: AnyObject) { 
    if field2.text == "true statement" { 
     fieldCheck2 = true 
    } 
    self.checkComplete() 
} 

func checkComplete() { 
    if fieldCheck1 == true && fieldCheck2 == true{ 
     // enable your Next Button 
    } 
} 

如果您有興趣,你也可以使用監控屬性來檢查,如果房產本身發生變化,按關閉該值和運行代碼:

var myBool: Bool = false { 
    willSet(newValue) { 
      if newValue == true { 
       // Run some code now that the bool is true 
      } 
    } 
} 
+0

感謝您的代碼示例!這比我想的要簡單得多。雖然我有這個標記的OS X,但您的示例絕對是一般用途,我可以利用它。再次感謝! – humcat

+0

隨時!像'@IBAction func field2Changed'這樣的方法本身是自動生成的,當你控制一個文本字段從接口生成器拖入Swift文件並將'outlet'改成'action'時,如果它在OS X上不同,它會相應改變!無論如何,邏輯是一樣的。 – Cole

1

你正在浪費CPU,因爲你在後臺線程上有一個while true循環,這個線程在循環內部並沒有做太多的工作(所以它只是在旋轉),當然,因爲你將大量的工作放到main線程也是如此。

當控制值發生變化時,您將希望使用target/action mechanism來監聽回調,並且必要時僅更改enabled。這項工作不需要使用後臺隊列/線程,因爲它會非常快。關鍵是隻有在必要時才能做到。

您還可以看看使用bindings自動更改enabled狀態。

這是更先進的,所以我不願意提及它,但你可能要考慮ReactiveCocoa,因爲它使這種簡單的表單驗證非常簡單。

+1

雖然我沒有將您的回覆標記爲答案是,你爲我未來的項目提供了一些很好的資源。感謝您抽出時間幫助您! – humcat