Предупреждение CoreData: несколько NSEntityDescription требуют подкласс NSManagedObject - PullRequest
0 голосов
/ 18 сентября 2018

Я неожиданно получаю кучу предупреждений на iOS12 / XCode 9. Почему существует несколько managedObjectModels?Приложение имеет только один файл * .xcdatamodeld, но в модели имеется несколько версий.

Это какая-то новая функция iOS12 Coredata и что я могу сделать, чтобы предотвратить это предупреждение, или я должен просто проигнорировать это?

2018-09-18 11:45:34.487073+1000 xxxxxxxxx[4422:1419983] [error] warning:     'Stats' (0x2812f1550) from NSManagedObjectModel (0x2806ff480) claims 'Stats'.
CoreData: warning:       'Stats' (0x2812f1550) from NSManagedObjectModel (0x2806ff480) claims 'Stats'.
2018-09-18 11:45:34.487084+1000 xxxxxxxxx[4422:1419983] [error] warning:     'Stats' (0x2812f3bd0) from NSManagedObjectModel (0x2806b18b0) claims 'Stats'.
CoreData: warning:       'Stats' (0x2812f3bd0) from NSManagedObjectModel (0x2806b18b0) claims 'Stats'.

Ответы [ 2 ]

0 голосов
/ 23 мая 2019

Я понял, как решить эту проблему. Вы должны создать один экземпляр NSEntityDescription в своем классе модульного теста и использовать его каждый раз, когда вы хотите создать объект, который соответствует описанию сущности. В приведенном ниже коде посмотрите на setup, tearDown и testFetchPerson ()

   var container: NSPersistentContainer!

   **var entityDescription: NSEntityDescription! // Insert only one instance into your managed object context * see setup//**

   override func setUp() {
       super.setUp()
       let bundle = Bundle(for: type(of: self))
       let url = bundle.url(forResource: "DivyaPracticeWorkspace", withExtension: "momd")!
       let managedObjectModel = NSManagedObjectModel(contentsOf: url)!
       container = NSPersistentContainer(name: "testContainer", managedObjectModel: managedObjectModel)
       let description = NSPersistentStoreDescription()
       description.type = NSInMemoryStoreType
       container.persistentStoreDescriptions = [description]
       container.loadPersistentStores(completionHandler: { (description, error) in
           if let error = error {
               print("\(error)")
           }
       })

       mockCoreData = CoreDataManager(container: container)
**// Insert only one entity description into the context
       entityDescription  = NSEntityDescription.entity(forEntityName: "Person", in: mockCoreData.mainContext)!**
   }


   override func tearDown() {
       super.tearDown()
       deleteAllObjects()
       mockCoreData = nil
       container = nil
   }

   private func deleteAllObjects() {
       let request: NSFetchRequest<Person> = Person.fetchRequest()
       do {
           let results = try mockCoreData.mainContext.fetch(request)
           for entry in results {
               mockCoreData.mainContext.delete(entry)
           }

           mockCoreData.saveChanges {
               [weak self] in
               guard let this = self else {
                   return
               }

               this.mockCoreData.mainContext.refreshAllObjects()
               this.mockCoreData.mainContext.reset()
               guard let store = this.container.persistentStoreCoordinator.persistentStores.first else {
                   return
               }
               do {
                   try this.container.persistentStoreCoordinator.remove(store)
               } catch let error {
                   print("\(error)")
               }
           }
       } catch let error {
           print("\(error)")
       }
   }

   func testFetchPerson() {
        var fetchSuccess = false
**// Create person entity using the entity description created in setup.
           let personEntity = Person(entity: entityDescription, insertInto: mockCoreData.mainContext)**

           personEntity.name = "Bob"
           personEntity.gender = Int32(0)

           mockCoreData.saveChanges(completion: nil)


           if let personFetched = mockCoreData.fetchPerson(name: "Bob")?.first {
               fetchSuccess = personFetched.gender == Int32(0) && personFetched.name == "Bob"
           }
       XCTAssertTrue(fetchSuccess)
   }
0 голосов
/ 22 октября 2018

Я только что решил ту же ошибку, когда использовал вычисляемое свойство для моего постоянного контейнера. Таким образом, каждый раз, когда приложение обращается к постоянному контейнеру / хранилищу, на диске создается новый экземпляр модели данных.

После того, как я изменил постоянный контейнер на свойство с отложенным хранением, проблема исчезла.

[обновление]

В настоящее время я использую отдельный класс для основного стека данных, где используется синглтон, как показано ниже:

class DataCtrl : NSObject {

static shared = DateCtrl()
var container: NSPersistentContainer?

private override init() { 
    container = NSPersistentContainer(name: "dataModelName")
}
func loadStore (completionHandler: @escaping () -> ()) {
self.container?.loadPersisentStores() { 
desc, err in ...
    completionHandler
    }
 }
}

Тогда я могу удобно использовать вычисляемое свойство в расширении tableViewController:

var container : persistentContainer { return DateCtrl.shared.container }

Конечно, вам нужно вызвать func loadStore в блоке AppDelegate didFinishLaunchingWithOptions, чтобы сначала загрузить постоянное хранилище, где с помощью DispatchGroup () в завершениеHandler для управления загрузкой модели данных контроллера первого представления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...