2017-02-01 10 views
0

このコードは、現在UIViewControllerに座っ:リファクタリングNSFetchedResultsController

lazy var categoryFRC: NSFetchedResultsController<Category> = { 
    let fetchRequest: NSFetchRequest<Category> = Category.fetchRequest() 
    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "text", ascending: true)] 
    let appDelegate = (UIApplication.shared.delegate) as! AppDelegate 
    let context = appDelegate.persistentContainer.viewContext 
    let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil) 
    frc.delegate = self 
    do { 
     try frc.performFetch() 
    } catch { 
     fatalError("Failed to initialize FetchedResultsController: \(error)") 
    } 
    return frc 
}() 

そして、これは私がforループでフェッチされたカテゴリを参照する方法です:私がアクセスしたい

let category = (self.categoryFRC.fetchedObjects?[index])! as Category 

同じCoreData異なるエンティティViewController

  1. コードを再構築する正しい方法は何ですか?

  2. 新しいクラスを作成しますか?

  3. NSFetchedResultsControllerDelegateをどうすれば処理できますか?

  4. fetchedResultsを参照するすべての数字は、 サブクラスNSFetchResultsControllerDelegateである必要がありますか?

答えて

0

私が行ったことは、ViewControllersからすべての非ビューレンダリング/ユーザーイベント処理を引き出し、そのロジックを別のクラスに配置することでした。あなたのケースでは、新しいクラスを作成してのViewControllerに続いて新しいクラスに

class DataController { 
    lazy var categoryFRC: NSFetchedResultsController<Category> = { 
    let fetchRequest: NSFetchRequest<Category> = Category.fetchRequest() 
    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "text", ascending: true)] 
    let appDelegate = (UIApplication.shared.delegate) as! AppDelegate 
    let context = appDelegate.persistentContainer.viewContext 
    let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil) 
    frc.delegate = self 

    do { 
    try frc.performFetch() 
    } catch { 
    fatalError("Failed to initialize FetchedResultsController: \(error)") 
    } 

    return frc 
    }() 
} 

をcategoryFRCロジックを入れたいDataControllerのインスタンスを格納します。

class ViewController { 
    var dataController : DataController! 

    func viewDidLoad() { 
    dataController = DataController() 
    dataController.categoryFRC.delegate = <Class that adopts NSFetchedResultsControllerDelegate> 
    } 
} 

その他の所見:

  • NSFetchedResultsControllerDelegateを採用する別のクラスを作成します。その後、categoryFRC.delegateを新しいクラスに設定します。このようにして、新しいクラスはビューコントローラではなくFRCデリゲートメソッドを処理します。

  • 怠惰なcategoryFRC定義からfrc.performFetch()の周りでdo/try/catchをプルします。 categoryFRCにアクセスするたびにフェッチを実行してもよろしいですか?私はdo/try/catchロジックを新しい関数に入れました。

  • あなたのforループを見て、fetchedObjectsがどうなるでしょうか?無名ですか?あなたが無価値の価値をアンラッピングしているので、クラッシュしないでしょうか?

+0

ありがとうございます! – bumber

+0

今、私のView ControllerはNSFetchedControllerDelegateを採用しており、delegateの関数はViewControllerで宣言されたtableViewを参照しています。だから、私はすべきことは、デリゲートの新しいクラスを作成し、デリゲート内でtableview変数を作成し、その後、FRCのデリゲートを設定した後、デリゲート内の変数をtableviewをポイントするように設定します。 – bumber

+0

あなたがViewController2で参照する必要があるときに新しいDataControllerインスタンスを作成しないようにsharedInstanceを作成することをお勧めしますか? – bumber

関連する問題