web-dev-qa-db-ja.com

NSManagedObjectにキャストできるが、エンティティのタイプにはキャストできないのはなぜですか?

新しいプロジェクトのコアデータにSwiftボイラープレートコードを使用しています。私の_.xcdatamodeld_ファイルには、単一の属性(Taskname)。

次のような_Task.Swift_ファイルがあります。

_import CoreData

class Task: NSManagedObject {
    @NSManaged var name: String
}
_

これを実行すると、動作します:

_var firstTask = NSEntityDescription.insertNewObjectForEntityForName("Task",
    inManagedObjectContext: managedObjectContext) as NSManagedObject

firstTask.setPrimitiveValue("File my TPS reports", forKey: "name")

var error: NSError?

managedObjectContext.save(&error)
_

IOSシミュレーターで使用されているSQLiteデータベースにアクセスして、行が追加されたことを確認することもできます。

ただし、上記とまったく同じコードを実行するときに_as Task_の代わりに_as NSManagedObject_を使用すると、_var firstTask_に関連付けられたエラーメッセージThread 1: EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)でクラッシュします…行。実行を継続すると、スレッド1を進めるたびに、スレッド1の上部に_EXC_BAD_ACCESS_と_0 misaligned_stack_error__が表示されます。

なぜこのキャストがこれすべてにつながるのでしょうか?

35

クラス名フィールドが実際にModule。Taskであることを確認してください。ここでModuleはアプリの名前です。 SwiftのCoreDataクラスは名前空間です。現在、オブジェクトはタスクとしてではなくNSManagedObjectとしてコンテキストから引き出されているため、as-castは失敗しています。

46
Ben Gottlieb

上記の提案をすべて試してみて、それらが私のために働いていない場合、これはさらにイライラします!

だから、これは私のために働くものです。

1- xcdatamodeldファイルを選択します

2-「モデル:現在の製品モジュール」が表示されている場合、すべてのエンティティの「データモデルインスペクター」にモジュールがないことを確認します。

3-アプリを削除してコアデータを消去する

4-それでも動作しない場合は、エンティティを削除して再生成します。

enter image description here

28
polarwar

Task.Swiftファイルを変更する必要があります。以下のように@objc(Task)を追加します

import CoreData

@objc(Task)
class Task: NSManagedObject {
    @NSManaged var name: String
}

プロジェクトにObjective-Cコードが含まれていない場合、これはバグだと思います。ただし、これが修正されるまでその行を追加する必要があります。

ここから学んだ。

11:45のYoutubeビデオ

12
Owen Zhao

私はまだ次の例外を受け取っているため、.xcdatamodelのクラスフィールドのみを変更しても機能しないと思います:致命的なエラー:クラスの未実装の初期化子 'init(entity:insertIntoManagedObjectContext :)'の使用

そこで、カスタムコードに次のコードを入力しました。

    init(entity: NSEntityDescription!,
    insertIntoManagedObjectContext context: NSManagedObjectContext!) {
        super.init(entity: entity, insertIntoManagedObjectContext: context)
}

突然、うまくいきました! NSManagedObjectは、カスタムクラスにダウンキャスト可能になりました。なぜこれが解決策なのか本当に理解できませんが、うまくいきます:)

6

XCode 7.1およびSwift 2.0での@Ben Gottliebの回答の更新

  1. クラスに@objcを追加します。 Owen Zhaoの回答をご覧ください。次に例を示します。
@objc
class ImageRecordMO: NSManagedObject{
  1. .xcdatamodledファイルを開きます。

  2. エンティティを選択し、右側のパネルでデータモデルインスペクターをクリックします。

  3. クラス名を入力します。下図を参照してください

  4. 現在の製品モジュールにするモジュールを選択します。下図を参照してください。

enter image description here

5
Anson Yao

Xcode 7 + Swift 2

Person.Swift

@objc(Person)
class Person: NSManagedObject {
}

データ・モデル

enter image description here

その後、単に呼び出す

let person = NSEntityDescription.insertNewObjectForEntityForName("Person", inManagedObjectContext: self.managedObjectContext) as! Person
4
Viktor Kucera

@objc()を追加し、coredataインターフェースでクラスを設定する必要がありました。 CoreDataの右ウィンドウの[エンティティ]領域には、[名前]および[クラス]テキストボックスがあります。 クラスはMSManagedObjectではなく、クラスでなければなりません。 単純な作業例 !を作成しました

2

私はこの数日でこの問題に遭遇しましたが、奇妙なことに、私のために働いた解決策は上記で提案されたものの変形でした。

生成されたサブクラスに@objc宣言を追加しましたが、オブジェクトモデルのクラス名のネームスペースプレフィックスを削除しました(サブクラスが生成された後のデフォルトプレフィックスは「PRODUCT_MODULE_NAME。」でした)。うまくいきました。

1
Julien Couvreur