web-dev-qa-db-ja.com

CoreData:警告:という名前のクラスをロードできません

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...
})
90
JimmyJammed

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

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

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

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

Up to XCode7 b3

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

Xcode 7.1のSwift 2.0で機能するバージョン
(Xcode 7ベータ4以上で動作します)

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

From Xcode7 beta 3

2。
また、頻繁に推奨事項に従うことも含める必要があります

@objc(Show)

クラスのすぐ上です。

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


また、castが適切なクラスに作成された管理対象オブジェクトであることを確認してください。デフォルトはNSManagedObjectになります。

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

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

この問題(この回答に関する4月3日のコメントも参照)はresolved inSwift 2およびAppleによるXCode 7ベータリリース。したがって、実際には、Mundiが回答したように、またはクラス名の前に「MyAppName.」を使用して、Swiftの@objc(myEntity)は必要ありません。動作を停止します。したがって、これらを削除し、Classの名前をFileに入れて、Current Working ModuleModuleとして選択し、歓声を上げてください。

Selecting current working module

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

Xcdatamodelの正しいクラスでは、次のようになります。

Setting the class

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

67
khunshan

Xcode 7と純粋にSwiftを使用する場合、実際にはremove@objc(MyClass)から自動生成NSManagedObjectサブクラス(生成元 Editor > Create NSManagedObject Subclass...)。

36
Santa Claus

Xcode 7ベータ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

12
Duncan Babbage

Xcode 6.1.1では、ベースエンティティがobjcクラス(NSManagedObject)のサブセットであるため、@ objc属性を追加する必要はありません( Swift Type Compatibility を参照してください。CoreDataでは完全なModule.Class名モジュール名は、[ビルド設定]-> [パッケージ]-> [製品モジュール名]で設定されているものであることに注意してください。デフォルトでは、これはTarget's名前

9
Jim Malak

XCode 7およびSwift 2.0バージョンでは、@ objc(NameOfClass)を追加する必要はなく、「データモデルインスペクターの表示」タブでエンティティ設定を変更するだけです。

名前-「あなたのエンティティ名」

クラス-「あなたのエンティティ名」

モジュール-「現在の製品モジュール」

enter image description here

エンティティクラスファイルのコードは次のようになります(私のコードでは、エンティティはファミリです)-

import UIKit
import CoreData

class Family: NSManagedObject {

   @NSManaged var member : AnyObject
}

この例は、xCode 7.0 + Swift 2.0を使用して私のアプリで正常に動作しています

5

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

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

3
Kof

また、キャストを実行するときは、(少なくとも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
Wizkid
1
WSJ

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

1
user3269767

私のために働いたのは(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
mark