2

HanekeSwift を使用してキャッシュされたデータを取得し、ビューが表示されるたびに swipeView のラベルに設定しています。私のコードは問題なくデータを取得しますが、cache.fetch()非同期であるため、メソッドを呼び出してビューを更新すると、ラベルが に設定されnilます。ビューをロードする前に、キャッシュされたデータが取得されるまで待つようにswiftに指示する方法はありますか?

以下のコードを参照してください。

override func viewWillAppear(animated: Bool) {
    updateEntries() // updates entries from cache when view appears
}

func updateEntries() {
    guard let accessToken = NSUserDefaults.standardUserDefaults().valueForKey("accessToken") as? String else { return }
    guard let cachedEntryKey = String(accessToken) + "food_entries.get" as? String else { return }
    cache.fetch(key: cachedEntryKey).onSuccess { data in
        ...
        // if successful, set labels in swipeView to data retrieved from cache
        ...
        dispatch_group_leave(dispatchGroup)
    } .onFailure { error in
        print(error)
        ...
        // if unsuccessful, call servers to retrieve data, set labels in swipeView to that data
        ...
        dispatch_group_leave(dispatchGroup)
    }
}

上記のコードをステップ実行すると、常にビューが表示されてからキャッシュ ブロックにステップ インします。viewWillAppear() で updateEntries() を完了させ、キャッシュ ブロックが実行されるまでそこから戻らないようにするにはどうすればよいですか? 事前にたくさんありがとう!

更新 1:

以下のソリューションはかなりうまく機能しており、呼び出しは正しい順序で行われます (notify ブロックの print ステートメントはキャッシュの取得後に実行されます) が、ビューはサーバーが呼び出されたときにラベルを非 nil 値で更新するだけです。たぶん、通知グループに間違ったコードをまとめているのでしょうか?

override func viewWillAppear(animated: Bool) {
    self.addProgressHUD()
    updateEntries() // updates entries from cache when view appears
}

func updateEntries() {
    guard let accessToken = NSUserDefaults.standardUserDefaults().valueForKey("accessToken") as? String else { return }
    guard let cachedEntryKey = String(accessToken) + "food_entries.get" as? String else { return }

    let dispatchGroup = dispatch_group_create()
    dispatch_group_enter(dispatchGroup)

    dispatch_group_async(dispatchGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
        cache.fetch(key: cachedEntryKey).onSuccess { data in
            ...
            // if successful, set labels in swipeView to data retrieved from cache
            ...
        } .onFailure { error in
            print(error)
            ...
            // if unsuccessful, call servers to retrieve data, set labels in swipeView to that data
            ...
        }
    }

    dispatch_group_notify(dispatchGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
        print("Retrieved Data")
        self.removeProgressHUD()
    }

}

更新 2:

また、ビューを切り替えると、コンソールにこの警告が表示されます。上記のコードでメインスレッドをロックしていると思います

「このアプリケーションは、バックグラウンド スレッドから自動レイアウト エンジンを変更しています。これにより、エンジンの破損や異常なクラッシュが発生する可能性があります。これは、将来のリリースで例外が発生する可能性があります。」

4

4 に答える 4

1

みんなからのOKの提案は、これに大いに役立ちました. 私はそれを手に入れたと思います。キャッシュ ブロックがメイン キューをブロックしていないことを確認する必要があります。以下のコードを参照してください

編集

この作業を行うために適切な調整を行うのを手伝ってくれた@Robに感謝します

let dispatchGroup = dispatch_group_create()
dispatch_group_enter(dispatchGroup)

cache.fetch(key: cachedEntryKey).onSuccess { data in
    ...
    // if successful, set labels in swipeView to data retrieved from cache
    ...
    dispatch_group_leave(dispatchGroup)
} .onFailure { error in
    print(error)
    ...
    // if unsuccessful, call servers to retrieve data, set labels in swipeView to that data
    ...
    dispatch_group_leave(dispatchGroup)
}

dispatch_group_notify(dispatchGroup, dispatch_get_main_queue()) {
    print("Retrieved Data")
    self.removeProgressHUD()
}
于 2016-09-05T14:53:42.620 に答える