2015-08-17 2 views
0

Я довольно новичок в языке программирования Swift, создавая графические интерфейсы и использую асинхронные рассылки в целом, поэтому, пожалуйста, простите этот вопрос, который, я думаю, - имеет мучительно простой ответ.Асинхронный диспетчер ресурсов в Swift

Что я пытаюсь сделать, так это отключить и снова включить кнопку 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 и несколько гигабайт оперативной памяти), который я предполагаю, что из-за тонну фоновых задач. Я перепутал где-то довольно плохо, ха-ха.

Мой вопрос в том, как я должен структурировать цикл while так, чтобы он постоянно проверял настройки, не выполняя при этом все мои ресурсы? Или есть более простой способ управления графическим интерфейсом?

Заранее благодарим за любые советы или помощь, которые вы можете дать!

+1

Почему цикл? Просто проверьте условия, когда значение изменилось. вы можете зарегистрировать обратный вызов для него. также ваш код не является потокобезопасным. Вы не можете использовать элемент пользовательского интерфейса из не основного потока. –

+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 и некоторые bools.

@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

Вы тратите впустую процессор, потому что у вас есть петля while true на фоновом потоке, который не очень много работает внутри цикла (так что он просто вращается), и, конечно, потому что вы заставляете много работать на основной нить.

Вы должны использовать target/action mechanism для прослушивания обратных вызовов при изменении значений управления и при необходимости изменять только enabled. Нет необходимости использовать фоновые очереди/поток для этой работы, так как это будет очень быстро. Ключ должен делать это только при необходимости.

Вы также можете использовать bindings для автоматического изменения состояния enabled.

И это еще более продвинуто, поэтому я не хочу упоминать об этом, но вы можете рассмотреть ReactiveCocoa, так как это упрощает простую проверку формы.

+1

Хотя я не отметил ваш ответ как ответ, вы дали мне несколько хороших ресурсов для моих будущих проектов. Спасибо, что нашли время, чтобы помочь! – humcat

Смежные вопросы