2016-04-23 9 views
0

基本的にNSFetchedResultsControllerが変更を検出していないように見えるので、ここで作成されている新しいオブジェクトが保存されているとは思われません。これは私が作成したデリゲートあたりと呼ばれている連絡先リストビューに戻るために行われ、ユーザの押した後新しい連絡先を追加した後にcontrollerDidChangeContextが呼び出されない

else if segue.identifier == "AddContact" { 
     let navigationController = segue.destinationViewController as! UINavigationController 
     let addViewController = navigationController.topViewController as! NewContactViewController 
     let contactEntity = NSEntityDescription.entityForName("Contact", inManagedObjectContext: context) 
     let newContact = Contact(entity: contactEntity!, insertIntoManagedObjectContext: context) 

     addViewController.contact = newContact 
     addViewController.context = newContact.managedObjectContext 
     addViewController.delegate = self 
    } 

。彼らは常に一致しているので、プッシュが正常に動作している時のコンテキストの何百万人を確認した後

func didFinishViewController(viewController:NewContactViewController, didSave:Bool) { 

    // 1 
    if didSave { 
     // 2 
     let context = viewController.context 
     context.performBlock({() -> Void in 
      if context.hasChanges { 
       do { 
        try context.save() 
       } catch { 
        let nserror = error as NSError 
        print("Error: \(nserror.localizedDescription)") 
        abort() 
       } 
      } 

      // 3 
      self.coreDataStack.saveContext() 
     }) 
    } 

が、変更が記録されているかのように思えます。 CoreDataStack.swiftもそうです。

//exablishes the directory to be used for the stack in SQLite fashion 
private lazy var applicationDocumentsDirectory: NSURL = { 
    let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) 
    return urls[urls.count-1] 
}() 

//establishes the object model that interacts with the GUI object data model 
private lazy var managedObjectModel: NSManagedObjectModel = { 
    let modelURL = NSBundle.mainBundle().URLForResource(self.modelName, withExtension: "momd")! 
    return NSManagedObjectModel(contentsOfURL: modelURL)! 
}() 

//establishes the coordinator that connects the managed context with the persistent store 
private lazy var psc: NSPersistentStoreCoordinator = { let coordinator = NSPersistentStoreCoordinator(
    managedObjectModel: self.managedObjectModel) 

    let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent(self.modelName + ".sqlite") 

    do { 
     let options = [NSMigratePersistentStoresAutomaticallyOption : true] 

     try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil) //establishes the actual persistent store 
    } catch { 
     print("Error adding persistent store.") 
    } 
    return coordinator 
}() 


//establishes the managed context by which managed objects interact in reading and writing 
lazy var context: NSManagedObjectContext = { 
    var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) 
    managedObjectContext.persistentStoreCoordinator = self.psc 
    return managedObjectContext 
}() 

func saveContext() { 
    if context.hasChanges { 
     do { 
      try context.save() 
     } catch { 
      let nserror = error as NSError 
      print("Error: \(nserror.localizedDescription)") 
      abort() 
     } 
    } 
} 

NSFetchedResultsController実装

// MARK: Fetched Results controller 
func contactListFetchedResultsController()-> NSFetchedResultsController { 

    fetchedResultController = NSFetchedResultsController(fetchRequest: contactListFetchRequest(), managedObjectContext: coreDataStack.context, sectionNameKeyPath: nil, cacheName: nil) 
    fetchedResultController.delegate = self 

    do { 
     try fetchedResultController.performFetch() 
    } catch let error as NSError { 
     print("Error: \(error.localizedDescription)") 
     abort() 
    } 

     return fetchedResultController 
} 

func contactListFetchRequest() -> NSFetchRequest { 

    let fetchRequest = NSFetchRequest(entityName: "Contact") 
    fetchRequest.fetchBatchSize = 20 

    let sortDescriptor = NSSortDescriptor(key: "firstName", ascending: true) 

    fetchRequest.sortDescriptors = [sortDescriptor] 

    return fetchRequest 
} 
+0

NSFetchedResultsControllerDelegateメソッドの実装を投稿できますか? –

+0

上に、それのすべてでなければなりません。 – ggworean

+0

NSManagedContextからの保存は、コンテキストに対して同期していますが、ディスクとは非同期です。 NSPersistentStoreCoordinatorに渡され、自身のスレッド内にディスクに保存されます。 –

答えて

0

あなたがNSFetchedresultsControllerDelegateメソッドを実装していない表示されます:あなたはUIスレッド上に既にあるとき

func controllerWillChangeContent(controller: NSFetchedResultsController) { 
    tableView.beginUpdates() 
} 

func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) { 
    switch type { 
    case .Insert: 
     tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Automatic) 
    case .Delete: 
     tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Automatic) 
    case .Move, .Update: 
     break 
    } 
} 

func controller(controller: NSFetchedResultsController, didChangeObject anObject: NSManagedObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) { 
    switch type { 
    case .Insert: 
     tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Automatic) 
    case .Delete: 
     tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Automatic) 
    case .Update: 
     tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .Automatic) 
    case .Move: 
     tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Automatic) 
     tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Automatic) 
    } 
} 

func controllerDidChangeContent(controller: NSFetchedResultsController) { 
    tableView.endUpdates() 
} 
+0

最後のコメントを書き留めてください。これを行い、まだ連絡先をリストに保存していない。 – ggworean

+0

コントローラでNSFe​​tchedResultsControllerDelegateプロトコルを採用していますか? –

+0

はい 'class ContactsViewController:ToolbarTabSuper、NSFetchedResultsControllerDelegate、ContactEntryDelegate' – ggworean

0

あなたはcontext.performBlockを持っていないのはなぜ?作業しているコンテキストが複数ありますか?子コンテキストがself.coreDataStack.saveContext()を呼び出した後を保存させながら

あなたが複数のコンテキストを使用していると仮定すると、あなたはperformBlock()として子コンテキストの前に、メインのコンテキストを保存しています。

これはすべてのUI関連のコードなので、UI全体のメインキューコンテキストを使用する方がよいでしょう。NSFetchedResultsControllerが通知の受信を開始すると思われます。

+0

子コンテキストは連絡先を編集するためのものです。 – ggworean

+1

ブレークポイントを設定していて、これがすべて起動していることを確認していますか?一般に、 'NSFetchedResultsController'発火の問題は、マルチコンテキストが正しく保存されていないか、または配線されていないことです。ブレークポイントは、すべてが正常に実行されていることを確認するのに役立ち、デリゲートメソッドが起動しているかどうかを確認できます。 –

+0

私は、コンテキストが各ビューにプッシュされていることを確認しています。しかし、リストビューで保存しようとすると問題が発生しています。これは、contactViewControllerからの一時連絡先がcontactListViewに転送されていないかのようです。 – ggworean

関連する問題