CoreData: предупреждение: не удается загрузить класс с именем


я дублирую существующее приложение Objective-C TV Show на новую версию Swift с помощью Xcode 6.1 и у меня возникли некоторые проблемы с CoreData.

Я создал модель из 4 объектов, создал их подкласс NSManagedObject (в Swift), и все файлы имеют правильный набор целей приложения (для "компиляции источников").

Я все еще получаю эту ошибку, когда я пытаюсь вставить новые сущности:

CoreData: предупреждение: не удается загрузить класс с именем 'Shows' для сущность "Шоу". Класс не найден, используя вместо него NSManagedObject по умолчанию.

несколько комментариев:

при сохранении в основные данные, я использую Родительский-дочерний контекст способ разрешить фоновую резьбу. Я делаю это, настроив ManagedObjectContext с помощью:

lazy var managedObjectContext: NSManagedObjectContext? = {
  // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
  let coordinator = self.persistentStoreCoordinator
  if coordinator == nil {
    return nil
  }
  var managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.MainQueueConcurrencyType)
  managedObjectContext.persistentStoreCoordinator = coordinator
  return managedObjectContext
}()

и путем сохранения данных с помощью:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
  var context = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
  context.parentContext = self.managedObjectContext!
  ...rest of core data saving code here...
})
11 82

11 ответов:

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

я смог избавиться от него в большинстве случаев убедившись, что класс установлен правильно в Редакторе моделей. В отличие от многих других сообщений SOF (включая ответы на этот вопрос), предложение включить модуль имя (например MyApp.Shows) и не помог мне.

убедитесь, что вы проверяете эти три пункта:

1.
версия, которая работает до Xcode 7 beta 3

Up to XCode7 b3

обратите внимание, что я исправил ваше имя сущности на более подходящее единственное число.

версия, которая работает для Swift 2.0 в Xcode 7.1
(Должен работать для Xcode 7 beta 4 и выше)

вам нужно удалить текст "текущий модуль продукта"в модуле!

From Xcode7 beta 3

2.
Вы также должны следовать частой рекомендации включить

@objc(Show)

чуть выше свой класс.

Примечание: если вы используете Xcode 7 beta 4 или более позднюю версию, этот шаг является необязательным.

3.
Также убедитесь, что cast созданный управляемый объект к правильному классу, так как по умолчанию будет просто NSManagedObject.

var newShow = NSEntityDescription.insertNewObjectForEntityForName("Show", 
                 inManagedObjectContext: context) as Show

SWIFT 2 / Xcode 7 Обновление:

этот вопрос (см. Мой комментарий 3 апреля на этот ответ) является разрешить in Swift 2 и XCode 7 бета-версия от Apple. Так что вам на самом деле сейчас не нужно @objc(myEntity) в Swift, как ответил Мунди или с помощью "MyAppName." перед названием класса. Он перестанет работать. Так что удалите их, просто положите Class имя File и выберите Current Working Module как модуль и ура!

Selecting current working module

но для тех, кто использует @objc(myEntity) в Swift (как и я), вы можете использовать это другое решение вместо того, чтобы работать гладко.

в xcdatamodel правильный класс В. Это должно выглядеть так:

Setting the class

вот так. Module.Class это шаблон для CoreData в Swift и XCode 6. Вам также понадобится такая же процедура при использовании Настраиваемые Политики класс В модельной политике или других материалах CoreData. примечание: в изображении имя и класс должны быть Car и MyAppName.Автомобиль (или как там называется ваша сущность). Вот,User это опечатка.

при использовании Xcode 7 и чисто Swift, я на самом деле должен был удалить@objc(MyClass) из моего авто-генерируемых NSManagedObject подкласс (вырабатывается из редактор>Создать NSManagedObject Подкласс...).

в Xcode 7 beta 2 (и я считаю 1), в конфигурации модели новый управляемый объект типа File устанавливается в модуль Current Product Module и класс объекта отображается в конфигурации как .File.

Module of managed object type set to "Current Product Module" in Xcode 7

удаление параметра модуля, чтобы он был пустым, или удаление полной остановки, чтобы имя класса в конфигурации было просто File являются эквивалентными действиями, так как каждое вызывает другое изменение. Сохранение этой конфигурации приведет к устранению ошибки описанный.

Module of managed object set to be blank in Xcode 7

в Xcode 6.1.1 вам не нужно добавлять атрибут @objc, так как базовая сущность является подмножеством класса objc (NSManagedObject) (см. Совместимость Типов Swift. В CoreData полный модуль.Имя класса является обязательным. Имейте в виду, что имя модуля-это то, что задано в настройках сборки - > упаковка - > имя модуля продукта. По умолчанию это значение равно $(PRODUCT_NAME:c99extidentifier), который будет цели.

С xCode 7 и Swift 2.0 версии, вам не нужно добавлять @objc (NameOfClass), просто измените настройки объекта в "показать инспектор модели данных" вкладку, как показано ниже -

Name - "Имя Вашей Сущности"

Class - "Your Entity Name"

Модуль - "Текущий Модуль Продукта"

enter image description here

код для файла класса сущностей будет похож (в моем коде сущность является семейством) -

import UIKit
import CoreData

class Family: NSManagedObject {

   @NSManaged var member : AnyObject
}

этот пример работает отлично в моем приложении с xCode 7.0 + swift 2.0

не забудьте заменить PRODUCT_MODULE_NAME с вашим именем модуля продукта.

при создании нового объекта необходимо перейти в Инспектор модели данных (последняя вкладка) и заменить PRODUCT_MODULE_NAME с вашим именем модуля, или это приведет к class not found ошибка при создании постоянного координатора хранилища.

вы также должны использовать (по крайней мере с Xcode 6.3.2) модуль.Класс при выполнении приведения, например: Предполагая, что ваш модуль( т. е. название продукта) - это еда, а ваш класс-фрукты

let myEntity =  NSEntityDescription.entityForName("Fruit", inManagedObjectContext: managedContext)

let fruit = NSManagedObject(entity: myEntity!, insertIntoManagedObjectContext:managedContext) as! Food.Fruit

Recap:

  • включить имя модуля при определении сущности в Редакторе модели данных (имя: фрукты, класс: еда.Фрукты)
  • при доступе к сущности в коде (т. е. SWIFT), приведите его с модулем.класс (например, питание.Фрукты)

изменение имени класса сущностей в Редакторе модели данных в соответствии с данным классом и добавление @objc(NameOfClass) чтобы файл каждого NSManagedObject прямо над объявлением класса решил эту проблему для меня во время модульного тестирования.

Я также столкнулся с подобной проблемой, выполните следующие действия, чтобы решить:

  1. родителем является NSManagedObject, а не NSObject
  2. модуль из сущность по умолчанию, а не"текущий модуль продукта"

то, что сработало для меня (Xcode 7.4, Swift), меняет имя класса на <my actual class name>.<entity name> в инспекторе сущностей, поле "класс".

мой инициатор подкласса управляемых объектов выглядит так:

    convenience init(<properties to init>) {
    let entityDescr = NSEntityDescription.entityForName("<entity class name>", inManagedObjectContext: <managed context>)
    self.init(entity: entityDescr!, insertIntoManagedObjectContext: <managed context>)}
    //init properties here