2017-05-17 2 views
0

検索テーブルがフィルタリングして検索結果のみを表示した後、40 KB(40000)の配列を持つプログラムを作成して、UITableViewに表示しています。UITableViewの行を削除するには時間がかかります

問題は、一度に多くの行を削除すると(たとえば30000+)、約10〜20秒かかり、使用することができないことです。あなたはこの問題の決定を示唆できますか?あなたは30K +細胞を持つテーブルを持っていることはありません

var allProducts = [Product]() 
@IBOutlet weak var searchTableView: UITableView! 
@IBOutlet weak var searchTextField: UITextField? 

var searchResults = [Product]() 

enum Action{ 
    case Insert 
    case Ignore 
    case Remove 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 
    searchTextField?.addTarget(self, action: #selector(ViewController.textFieldDidChanged(_:)), for: .editingChanged) 
    DBBrain().getAllAlcProducts() { [weak self] products in 
     self?.allProducts = products 
    } 
} 

func textFieldDidChanged(_ sender: UITextField){ 
    DispatchQueue.global(qos: .userInitiated).async { [weak self] in 
     let text = sender.text!.lowercased() 
     let res = self!.allProducts.filter({ $0.name.lowercased().contains(text) }) 
     if self?.searchTextField?.text != nil && text == self!.searchTextField!.text!{ 
      if let values = self?.getIndexes(forResults: res){ 
       self?.searchResults = res 
       self?.updateTable(action: values.0, indexes: values.1) 
      } 
     } 
    } 
} 

private func getIndexes(forResults products: [Product]) -> (Action, [IndexPath]){ 
    var indexes = [IndexPath]() 
    var action = Action.Ignore 
    if searchResults.count > products.count{ 
     var newCounter = 0 
     for x in 0..<searchResults.count { 
      if products.isEmpty || searchResults[x].id != products[newCounter].id { 
       indexes.append(IndexPath(row: x, section: 0)) 
      }else { 
       if newCounter < products.count - 1{ 
        newCounter += 1 
       } 
      } 
     } 
     action = Action.Remove 
    }else if searchResults.count < products.count{ 
     var oldCounter = 0 
     for x in 0..<products.count { 
      if searchResults.isEmpty || searchResults[oldCounter].id != products[x].id { 
       indexes.append(IndexPath(row: x, section: 0)) 
      }else { 
       if oldCounter < searchResults.count - 1 { 
        oldCounter += 1 
       } 
      } 
     } 
     action = Action.Insert 
    } 
    return (action, indexes) 
} 

private func updateTable(action: Action, indexes: [IndexPath]) { 
    DispatchQueue.main.async { [weak self] in 
     if action != .Ignore { 
      if action == .Remove { 
       self?.searchTableView.beginUpdates() 
       self?.searchTableView.deleteRows(at: indexes, with: .fade) 
       self?.searchTableView.endUpdates() 
      }else if action == .Insert { 
       self?.searchTableView.beginUpdates() 
       self?.searchTableView.insertRows(at: indexes, with: .fade) 
       self?.searchTableView.endUpdates() 
      } 
     } 
    } 
} 


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return searchResults.count 
} 
+1

あなたのアプリはこの10-20秒間フリーズしますか?その場合は、削除が非同期で実行されていることを確認する必要があります。 –

+2

なぜ30000行を一度に削除しますか?あなたはあなたがしていることに関するより多くの関連性の高い情報であなたの質問を更新する必要があります。 – rmaddy

+0

"無限リスト"テクニックを読んでいるかもしれません。これは、UITableView(またはそれに関する任意のリスト)の多数の要素を処理する方法を理解するかもしれません。インスクリーンのみであることと、変更後にインスクリーンであることを考慮してください。 –

答えて

0

tableview.reloadData()適していません)。それはメモリのばかげた使い方です。 rowsForSectionデリゲートメソッドの最大セル数に上限を設定する必要があります。

検索結果の数を取得し、カウントが(たとえそれが多数である)、30かそこらよりも大きければ、それは非常によくスーパー巨大な配列を持つこともできる30

に設定し、あまりにも。あなたがそれらのために細胞を作っていないとしても、それは多くのメモリ使用量です。

+0

はい、ありがとう、他の人に感謝します。私は、より少ない細胞を提示するためにアルゴリズムを再設計しようと考えて、ここに投稿してください。 – KacaTuk

関連する問題