Не удалось найти конкретный подкласс 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]()
Ответы
Ответ 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 должен быть определением класса. В этом случае не будет предупреждений и т.д. введите здесь описание изображения