2016-12-02 1 views
1

Swift 3では、ユーザがボタンを押してキャンセルできるループがあります。ループ内でいくつかのチェックが行われます。チェックの後、タスクは1分間スリープ状態になります。エンドレスループ内で自分自身を待ちますが、ユーザは毎回キャンセルできます

let delayQueue = DispatchQueue(label: "com.myApp.queue3", qos: .utility) 
let additionalTime: DispatchTimeInterval = .seconds(3) 

repeat { 
    delayQueue.asyncAfter(deadline: .now() + additionalTime) { self.update() } 
} while !self.stop 

自体が「停止」ユーザー を待っているすべての時間を実行するために必要なループでタスクを呼び出す場合でも、ユーザーが停止ボタンをクリックしたこと、を示しています。 CPUの消費が浪費していますか?どのようにしてこのループが常に行われるのを避けることができますか?

答えて

2

代わりにTimerを使用してください。

var timer: Timer? 
let timeInterval: TimeInterval = 3 

func didPressCancelButton() { 
    timer?.invalidate() 
} 

func beginUpdates() { 
    timer = Timer.scheduledTimer(
     timeInterval: timeInterval, 
     target: self, 
     selector: #selector(self.update), 
     userInfo: nil, 
     repeats: true 
    ); 
} 

func update() { 
    print("Updated") 
} 
+0

ありがとうございます、それは私が好きなほど簡単です。 –

+0

あなたはようこそ! –

+0

1つの質問:上記の解決策では、タイマーはメインDispatchQueue上でタスクを呼び出していますか?メインキューで実行されるダイアログ項目の更新がないため、別のキューとして開始する必要があります。ユーティリティ。 –

1

外側のループを持つスレッドで実行を遅らせる代わりに、代わりにループをスレッドに入れてスリープさせることができます。

import Foundation 

class YourUpdatingClass { 

    private let updateQueue: OperationQueue 
    init() { 
     updateQueue = OperationQueue() 
     updateQueue.name = "com.myApp.queue3" 
     updateQueue.qualityOfService = .utility 
    } 

    private var updateOperation: BlockOperation? 

    @IBAction func startUpdating() { 
     guard updateOperation == nil else { 
      // In case if updating already started 
      return 
     } 

     updateOperation = BlockOperation { [weak self] in 
      while true { 
       Thread.sleep(forTimeInterval: 3) 
       self?.update() 
      } 
     } 

     updateQueue.addOperation(updateOperation!) // we just created updateOperation, so we can use `!`, but use it with caution 
    } 

    @IBAction func stopUpdating() { 
     updateOperation?.cancel() 
     updateOperation = nil 
    } 

    private func update() { 
     print("update") // Whatever your update does 
    } 

} 

あなたは更新が永遠にwhileループに含まれています。これは3秒ごとに軽くなります。

ループ内のいくつかのvarをチェックするのではなく、キャンセル操作で停止を管理します。

+1

グレート。もっと複雑になるなら、私はこの解決法を使用します。より一般的な解決策です。どうもありがとう! –

関連する問題