CoreData: warning: невозможно загрузить класс с именем - программирование

CoreData: warning: невозможно загрузить класс с именем

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

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

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

CoreData: warning: Невозможно загрузить класс с именем "Показывать" для объекта "Шоу". Класс не найден, используя вместо этого NSManagedObject по умолчанию.

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

При сохранении в Core Data я использую контекст parent-child, чтобы разрешить фоновый поток. Я делаю это, настраивая 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...
})
4b9b3361

Ответ 1

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

Мне удалось избавиться от него в большинстве случаев , убедившись, что класс правильно задан в редакторе моделей. В отличие от многих других сообщений 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.
Также убедитесь, что трансформировать созданный управляемый объект в соответствующий класс, поскольку по умолчанию будет просто NSManagedObject.

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

Ответ 2

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

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

Выбор текущего рабочего модуля

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

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

Setting the class

Здесь вы идете. Module.Class - это шаблон для CoreData в Swift и XCode 6. Вам также понадобится такая же процедура при использовании класса Custom Policy в Model Policy или других материалах CoreData. Примечание. На изображении Name и Class должны быть Car и MyAppName.Car(или любое другое имя вашего объекта). Здесь User является опечаткой.

Ответ 3

При использовании Xcode 7 и чисто Swift мне действительно нужно удалить @objc(MyClass) из моего автоматически сгенерированного подкласса NSManagedObject (сгенерированного из Editor > Create NSManagedObject Subclass...).

Ответ 4

В 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

Ответ 5

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

Ответ 6

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

Название - "Ваше имя сущности"

Класс - "Ваше имя объекта"

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

введите описание изображения здесь

Код для класса Entity будет похож (в моем коде Entity is Family) -

import UIKit
import CoreData

class Family: NSManagedObject {

   @NSManaged var member : AnyObject
}

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

Ответ 7

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

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

Ответ 8

Вам также необходимо использовать (по крайней мере, с Xcode 6.3.2) Module.Class при выполнении вашего броска, например: Предполагая, что ваш модуль (то есть название продукта) - это Food, а ваш класс - Fruit

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

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

Резюме:

  • Включить имя модуля при определении объекта в редакторе модели данных (название: Fruit, Class: Food.Fruit)
  • При доступе к сущности в коде (т.е. SWIFT), нарисуйте его с помощью Module.class(например, Food.Fruit)

Ответ 9

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

Ответ 11

Что сработало для меня (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