Не удалось найти конкретный подкласс NSManagedObject - программирование

Не удалось найти конкретный подкласс NSManagedObject

Я работаю над разработкой приложения с помощью Core Data. Когда я создал экземпляр, используя:

let entity = NSEntityDescription.entityForName("User", inManagedObjectContext: appDelegate.managedObjectContext)
let user = User(entity: entity, insertIntoManagedObjectContext: appDelegate.managedObjectContext)

Я получил предупреждение в журнале:

CoreData: warning: Unable to load class named 'User' for entity 'User'.  Class not found, using default NSManagedObject instead.

Как я могу это исправить?

И еще один вопрос: как я могу определить метод экземпляра в подклассе NSManagedObject?

Edit:

Я определил класс объекта, как показано на следующем скриншоте:

enter image description here

4b9b3361

Ответ 1

Обновление для Xcode 7 (окончательное): Превращение имени модуля в класс (как в Xcode 6 и ранних бета-версиях Xcode 7) больше не требуется. Документация Apple Реализация основных подклассов управляемого объекта данных соответственно обновлены.

Инспектор модели данных теперь имеет два поля "Класс" и "Модуль" для объекта:

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

Когда вы создаете подкласс Swift управляемого объекта для объекта, Поле "Модуль" установлено на "Текущий модуль продукта" и с этой настройкой создание экземпляров работает как в основном приложении, так и в модульных тестах. Подкласс управляемого объекта не должен быть помечен @objc(classname) (это было отмечено в fooobar.com/questions/49146/...).

В качестве альтернативы вы можете очистить поле "Модуль" (он покажет "Нет" ) и отметьте подклассы управляемых объектов с помощью @objc(classname) (это наблюдалось в fooobar.com/questions/49146/...).


Примечание. Этот ответ был первоначально написан для Xcode 6. Были некоторые изменения в различных бета-версиях Xcode 7 с в отношении этой проблемы. Поскольку это принятый ответ со многими upvotes и ссылки на него, я попытался обобщить ситуацию для текущей окончательной версии Xcode 7.

Я сделал и свое "исследование" и прочитал все ответы на этот вопрос и аналогичный вопрос CoreData: предупреждение: невозможно загрузить класс с именем. Таким образом, атрибуция распространяется на всех из них, даже если я не перечислите их специально!


Предыдущий ответ для Xcode 6:

Как описано в Внедрение подклассов управляемых объектов с основными данными, вы должны префикс имени класса сущностей в поле "Класс" в инспекторе модели объекта с именем вашего модуля, например "MyFirstSwiftApp.User".

Ответ 2

Как примечание. Я была такая же проблема. И все, что мне нужно было сделать, это добавить @objc(ClassName) в мой файл класса.

Пример:

@objc(Person)
class Person { }

И это решило мою проблему.

Ответ 3

Принятый ответ на этот вопрос помог мне решить ту же проблему, но у меня было предостережение, которое я считал полезным для других. Если в имени вашего проекта (модуля) есть пробел, вы должны заменить пробел знаком подчеркивания. Например:

Сущность: MyEntity Класс: My_App_Name.MyClass

Ответ 4

Не забудьте удалить модуль:

enter image description here

Ответ 5

В зависимости от того, что вы используете как приложение против тестов, проблема может заключаться в том, что приложение ищет <appName>.<entityName>, а при запуске в качестве теста оно выглядит как <appName>Tests.<entityName>. Решение, которое я использую в это время (Xcode 6.1), НЕ должно заполнить поле Class в пользовательском интерфейсе CoreData и сделать это вместо кода.

Этот код обнаружит, что вы работаете как приложение против тестов, и используйте правильное имя модуля и обновите managedObjectClassName.

lazy var managedObjectModel: NSManagedObjectModel = {
    // The managed object model for the application. This property is not optional...
    let modelURL = NSBundle.mainBundle().URLForResource("Streak", withExtension: "momd")!
    let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)!

    // Check if we are running as test or not
    let environment = NSProcessInfo.processInfo().environment as [String : AnyObject]
    let isTest = (environment["XCInjectBundle"] as? String)?.pathExtension == "xctest"

    // Create the module name
    let moduleName = (isTest) ? "StreakTests" : "Streak"

    // Create a new managed object model with updated entity class names
    var newEntities = [] as [NSEntityDescription]
    for (_, entity) in enumerate(managedObjectModel.entities) {
        let newEntity = entity.copy() as NSEntityDescription
        newEntity.managedObjectClassName = "\(moduleName).\(entity.name)"
        newEntities.append(newEntity)
    }
    let newManagedObjectModel = NSManagedObjectModel()
    newManagedObjectModel.entities = newEntities

    return newManagedObjectModel
}()

Ответ 6

Если вы используете дефис в имени вашего проекта, например "My-App", используйте вместо подчеркивания символ подчёркивания, например "My_App.MyManagedObject". В общем, посмотрите имя файла xcdatamodeld и используйте тот же префикс, что и в этом имени. То есть "My_App_1.xcdatamodeld" требует префикса "My_App_1"

Ответ 7

Это может помочь тем, кто испытывает ту же проблему. Я был с Swift 2 и Xcode 7 beta 2.

Решение в моем случае состояло в том, чтобы прокомментировать @objc(EntityName) в EntityName.swift.

Ответ 8

У меня было такое же предупреждение, хотя мое приложение, похоже, отлично работало. Проблема заключалась в том, что при запуске редакторa > Создание подкласса NSManagedObject на последнем экране я использовал местоположение группы по умолчанию, без отображения или проверки целевых объектов, которые сохранили подкласс в верхней директории MyApp, где находился MyApp.xcodeproj.
Предупреждение исчезло, когда я вместо этого изменил группу, чтобы быть в подпапке MyApp, и проверил цель MyApp.

Ответ 9

Кстати, будьте внимательны, что вы добавляете в качестве префикса: Мое приложение называется "ABC-def", а Xcode преобразует "-" в "_".

Чтобы быть в безопасности, найдите файлы проекта и посмотрите, что он говорит для вашей модели данных (например, "ABC_def.xcdatamodeld" ) и используйте то, что там написано ТОЧНО!!!

Ответ 10

Вышеуказанные ответы были полезны. Эта быстрая проверка работоспособности может сэкономить вам некоторое время. Перейдите в Project > Build Phases > Compile Sources и удалите xcdatamodeld и ваши файлы модели с помощью кнопки "-", а затем добавьте их обратно с помощью кнопки "+". Перестроить - это может позаботиться об этом.

Ответ 11

Вышеупомянутые ответы помогли мне решить другую проблему, связанную с Objective-C (возможно, это поможет кому-то):

Если вы реорганизовали имена сущностей, не забудьте также изменить "класс" в "Панель служебных программ".

Ответ 12

Вышеприведенные ответы помогли мне, но это может помочь кому-то. Если вы, как я, вы их делали и все еще испытываете проблемы, не забудьте просто "очистить свой проект". Для XCode8, Product > Clean. Затем снова запустите.

Ответ 13

В Xcode 7 имена сущностей и классов могут быть одинаковыми, но Codegen должен быть определением класса. В этом случае не будет предупреждений и т.д. введите здесь описание изображения