【Swift4】UITableViewCellにUISwitchをつけたがフリーズして困った件。

ちょっと前に、UITableViewCellにUISwitchを乗せるのをやったのですが、↓

【Swift4】UITableViewCellにUISwitchをつけたがindexPath.rowを受け取るのが大変だった件。 | iPhoneアプリ備忘録

その後いじってるとスイッチを動かしたあとぐぐっと動いてフリーズしてしまいました。
エラーなどは出ずほんとにフリーズしてしまうのです。

いろいろと動かしてみた結果、スイッチを動かした後すぐにuserDefaultsでデータを保存しようとするとフリーズしてしまうようでした。
初めに別メソッドにしてディスパッチで保存を隔離してみたのですが、駄目でした。

    func saveAlarmArray() {
        //TableViewのUISwitchで呼ばれたときに動作がおかしくなるため非同期処理
        DispatchQueue.global().async {
        // NSUserDefaultsの取得
        let defaults = UserDefaults.standard
            defaults.set(self.alarmArray, forKey:  "alarmArray")
        }
    }

なんか一時的にうまく行ったのですが、やはり時々フリーズすることが有り使えませんでした。
んでいろいろと検索してみると似たような症例がいくつか…。

参考サイト
ios – テーブルビューリロードセクションがクラッシュする
iOS8のUITableViewの自爆機能について(笑)

どうもUITableViewを使っていてUITableViewCell.accessoryViewプロパティにUISwitch等のUIView関連を設定していてセクションを更新しようとするとおかしくなるらしいです。
まあ良くは理解してませんが。
スイッチがアニメーションしているときに更新等が入ると止まっちゃうようです。

なのでアニメーションが終わってから処理をしたら大丈夫かなと想像しているとこちらで解法が載っていました。

参考サイト
reloadData処理後に処理を行いたい – Qiita

参考サイトからの転載

-func test()
{

    UIView.animate(
        withDuration: 0.0,
        animations:{
            // リロード
            self.tableView.reloadData()
        }, completion:{ finished in
            if (finished) { // 一応finished確認はしておく
                /* やりたい処理 */
            }
    });
}

んで、自分がしたかったのは保存なので、

    //保存
    func saveAlarmArray() {
        UIView.animate(
            withDuration: 0.0,
            animations:{
                // リロード
//                self.tableView.reloadData()
        }, completion:{ finished in
            if (finished) { // 一応finished確認はしておく
                /* やりたい処理 */
                        // NSUserDefaultsの取得
                        let defaults = UserDefaults.standard
                            defaults.set(self.alarmArray, forKey:  "alarmArray")
            }
        });
        
        // リロード
        self.tableView.reloadData()
    }

こんな感じになりました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です