CoreData:警告:指定されたクラスをロードできません


94

Xcode 6.1を使用して、既存のObjective-C TV Showアプリを新しいSwiftバージョンに複製していますが、CoreDataに問題があります。

4つのエンティティのモデルを作成し、それらのNSManagedObjectサブクラスを(Swiftで)作成しました。すべてのファイルに適切なアプリターゲットセット(「ソースのコンパイル」用)があります。

新しいエンティティを挿入しようとすると、このエラーが発生します。

CoreData:警告:エンティティ 'Shows'の 'Shows'という名前のクラスをロードできません。クラスが見つかりません。代わりにデフォルトのNSManagedObjectを使用します。

いくつかのコメント:

Core Dataに保存するとき、私は親子コンテキストの方法を使用してバックグラウンドスレッドを許可します。これを行うには、次を使用して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...
})

回答:


177

この警告は、Swift実装の詳細が解決されている間に対処しなければならない問題の1つです。警告は誤って発生します。つまり、以下に概説する手順を実行しなくても、セットアップが機能する可能性があります。

ほとんどの場合、モデルエディターでクラスが正しく設定されていることを確認することで、それを取り除くことができました。他の多くのSOF投稿(この質問への回答を含む)とは異なり、モジュール名(などMyApp.Shows)を含めるという提案役に立ちませんでした。

次の3つの項目を確認してください。

1.
Xcode 7ベータ3まで動作するバージョン

XCode7 b3まで

エンティティ名をより適切な単数形に修正したことに注意してください。

Xcode 7.1のSwift 2.0で動作するバージョン
(Xcode 7ベータ4以上で動作するはずです)

モジュールのテキスト「現在の製品モジュール」を削除する必要があります!

Xcode7ベータ3から

2.
また、頻繁な推奨事項に従ってください

@objc(Show)

クラスのすぐ上。

:Xcode 7ベータ4以降を使用している場合、この手順はオプションです。

3.
また、デフォルトはなので、作成した管理対象オブジェクトを適切なクラスにキャストしてくださいNSManagedObject

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

3
ありがとう!私は推奨される命名規則の更新を行いましたが、「クラスをロードできません...」エラーを修正するトリックを実行しているように見えるのは '@objc(Show)'でした。とても有難い!
JimmyJammed 2014年

こんにちは@ムンディ。どうもありがとうございます!ソースがどこにあったか覚えていますか?
iamdavidlam

1
例えばこの質問を見てください。何が起こっているのかを理解するのに十分な情報があります。
ムンディ


1
@Mundi、もう一度答えを更新したいかもしれません。クンシャンの回答更新を参照してください。
Suragch

75

SWIFT 2 / XCODE 7アップデート:

この問題(この回答に関する4月3日のコメントも参照)は、AppleによるSwift 2およびXCode 7ベータリリースで解決されています。したがって、実際には、Mundiによって回答されたクラス名の前に" " を使用する必要はありません。動作しなくなります。これらを削除し、ファイルに名前を入力して、モジュールとして選択し 、歓声を上げるだけです!@objc(myEntity)MyAppName.ClassCurrent Working Module

現在動作しているモジュールの選択

しかし@objc(myEntity)、Swiftで(私のように)使用している場合は、代わりにスムーズに動作するこの他のソリューションを使用できます。

xcdatamodelで正しいクラスを入力します。次のようになります。

クラスの設定

どうぞ。Module.Classは、SwiftおよびXCode 6のCoreDataのパターンです。モデルポリシーまたは他のCoreDataのものでカスタムポリシークラスを使用する場合も同じ手順が必要です。 注:画像では、名前とクラスはCarとMyAppName.Car(またはエンティティの名前)である必要があります。ここにUserタイプミスがあります。


このソリューションの問題は、エンティティークラスの自動生成が正しく機能しなくなることです(モジュール名を持つクラスが1つだけ生成されます)。参照:正しく生成されないNSManagedObjectサブクラスの作成
ミロス2015

NSManagedObjectエンティティークラスを生成した後、ソリューションを適用する必要があります。おそらくxcode 6.xxのバグは削除される予定です。
クンシャン2015

2
はい、これは間違いなく解決されます。自動生成されたクラスは、すでに@objc(<エンティティインスペクターに入力されたクラス名>)で装飾されている必要があります。
ミロス2015

2
まだこれを読んでいる人のために。' MyAppName.Car ' を使用しても機能しませんでした。 ' MyAppNameを削除すると機能しました。'部分。つまりCar、両方の分野でうまくいったのです。
ギデオン

1
あなたチャンプ!!!! let person = NSEntityDescription.insertNewObject(forEntityName: "Person"、into:context)as!人
Abhimanyu Rathore 2017

36

Xcode 7と純粋にSwiftを使用するとき、自動生成されたサブクラス(> から生成)から実際に削除する 必要がありました。@objc(MyClass)NSManagedObjectEditorCreate NSManagedObject Subclass...


4
この回答を投稿してくれてありがとう。私は壁に頭をぶつけ始めようとしていました。
Zia

ここで同じ問題-バグを送信しました。
MirekE 2015年

私も働いた。それを削除する必要がありました。奇妙な。
ケント

私の実験によると、それは偽陽性のように見えます。
ムンディ

私はそれを削除して現在の製品モジュールを設定する必要があり、それが機能した場合にのみ機能しました
Oleg Sherman

13

Xcode 7ベータ2(および私は1と考えています)では、モデル構成でタイプの新しい管理対象オブジェクトがFileモジュールに設定されCurrent Product Module、オブジェクトのクラスが構成としてとして表示されます.File

Xcode 7で「現在の製品モジュール」に設定された管理対象オブジェクトタイプのモジュール

モジュール設定を削除して空白にするか、完全停止を削除して構成内のクラス名をFileそのままにすることは、それぞれが他の変更を引き起こすため、同等のアクションです。この構成を保存すると、説明されているエラーが削除されます。

Xcode 7で空白に設定された管理オブジェクトのモジュール


9

Xcode 6.1.1では、基本エンティティはobjcクラス(NSManagedObject)のサブセットであるため、@ objc属性を追加する必要はありません(Swiftタイプの互換性を参照してください。CoreDataでは、完全なModule.Class名が必要です。モジュールに注意してください。 nameは、Build Settings-> Packaging-> Product Module Nameで設定されるものです。デフォルトでは、これはターゲットの名前となる$(PRODUCT_NAME:c99extidentifier)に設定されています。


はい!これが最新の答えです(xcode 6.3.2)。正しいバンドル名を使用することが重要です。私の場合、それはに変換my-productされmy_product、これがCore Dataにすべての違いをもたらしました。
SimplGy

5

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を使用した私のアプリで正常に動作しています


3

PRODUCT_MODULE_NAME製品モジュール名に置き換えることを忘れないでください。

新しいエンティティが作成されたら、データモデルインスペクター(最後のタブ)に移動PRODUCT_MODULE_NAMEしてモジュール名に置き換える必要があります。そうしないとclass not found、永続ストアコーディネーターの作成時にエラーが発生します。


2

たとえば、キャストを実行するときは、少なくとも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、クラス:Food.Fruit)
  • コード(SWIFTなど)でエンティティにアクセスする場合は、Module.class(Food.Fruitなど)でキャストします。

ありがとう、2番目のポイントは非常に重要です。キャストするときに「Module.Class」を使用する必要がありました。
Zoyt


1

問題のクラスに対応するようにデータモデルエディタでエンティティクラス名を変更し@objc(NameOfClass)、クラス宣言の真上にある各NSManagedObjectのファイルに追加すると、ユニットテスト中にこの問題が解決しました。


0

私(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

0

Xcode 11.5の場合:Codegenプロパティがクラス定義の場合、およびxcdatamodelで作成したエンティティの提案を取得していない場合。Xcodeを終了して、プロジェクトを再度開いてみてください。わたしにはできる。この回答は、提案を得られない場合にのみ使用できますが、ファイルが生成されない場合は、上記の回答を試してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.