NSManagedObjectクラスがあります
class Disease: NSManagedObject {
@NSManaged var diseaseId: String
@NSManaged var diseaseName: String
@NSManaged var dogBreed: NSSet
}
DogBreedに新しい関係を追加するにはどうすればよいですか? var typeをNSMutableSetに変更すると、変更はデータベースに保存されません。何か案は?
Xcode7およびSwift 2.0の時点で、 リリースノート 17583057は次のように述べています。
NSManaged属性をメソッドとプロパティと共に使用して、コアデータの自動生成されたKey-Value-Coding準拠の多対多のアクセサーにアクセスできます。
@NSManaged var employees: NSSet
@NSManaged func addEmployeesObject(employee: Employee)
@NSManaged func removeEmployeesObject(employee: Employee)
@NSManaged func addEmployees(employees: NSSet)
@NSManaged func removeEmployees(employees: NSSet)
これらは、NSManagedObjectサブクラスで宣言できます。 (17583057)
したがって、次のメソッドを宣言するだけで、残りはCoreDataが処理します。
@NSManaged func addDogBreedsObject(dogBreed: DogBreed)
@NSManaged func removeDogBreedsObject(dogBreed: DogBreed)
@NSManaged func addDogBreeds(dogBreeds: NSSet)
@NSManaged func removeDogBreeds(dogBreeds: NSSet)
厳密な型システムのため、Swiftは動的ランタイムアクセサーを生成できません。 Disease
クラスの拡張を作成し、欠落したメソッドを手動で追加できます。これがコードです。
extension Disease {
func addDogBreedObject(value:DogBreed) {
var items = self.mutableSetValueForKey("dogBreed");
items.addObject(value)
}
func removeDogBreedObject(value:DogBreed) {
var items = self.mutableSetValueForKey("dogBreed");
items.removeObject(value)
}
}
備考:
拡張子Disease+CoreData.Swift
の個別のファイルを作成することをお勧めします。これは、CoreData
モデルを再生成するときにコードがオーバーライドされないようにするのに役立ちます。
管理対象オブジェクトの1つに関係を作成するだけで十分です。2番目のオブジェクトは、後方参照で更新されます。 (Objective-Cの場合と同じ)
重要:すべてを機能させるには、CoreDataモデルのエンティティのクラス名にモジュール名が含まれていることを確認する必要があります。例えば。 MyProjectName.Disease
簡単なアプローチを探しているなら、これを使ってください。
import CoreData
extension NSManagedObject {
func addObject(value: NSManagedObject, forKey: String) {
var items = self.mutableSetValueForKey(forKey);
items.addObject(value)
}
}
実装:
department.addObject(section, forKey: "employees")
それを必要とするすべてのNSManageObjectクラスに同じメソッドを書く代わりに。
実際には、次のように書くことができます。
@NSManaged var dogBreed: Set<DogBreed>
そして、insert
のremove
メソッドとSet
メソッドを直接使用します。
@Nazの拡張として。そして@Ashのコメントと組み合わせて。 xCode 6.3.1の唯一の実用的なソリューションを見つけました
import CoreData
extension NSManagedObject {
func addObject(value: NSManagedObject, forKey: String) {
self.willChangeValueForKey(forKey, withSetMutation: NSKeyValueSetMutationKind.UnionSetMutation, usingObjects: NSSet(object: value) as Set<NSObject>)
var items = self.mutableSetValueForKey(forKey);
items.addObject(value)
self.didChangeValueForKey(forKey, withSetMutation: NSKeyValueSetMutationKind.UnionSetMutation, usingObjects: NSSet(object: value) as Set<NSObject>)
}
}
Swiftの多対多の関係にオブジェクトを正しく追加するには、willChangeハンドラーとdidChangeハンドラーを呼び出す必要があります。
myManagedObject.addObject(value, forKey: "yourKey")
@Nycenは、自動的に実装されたメソッドを使用したXcode 7の最適なソリューションを提供しますが、NSOrderedSet
の問題はほとんど信じられないほど存在することに注意してください( この質問 を参照)。したがって、関係にNSOrderedSet
を使用する場合はNSSet
でも、回避策を使用する必要があります。
(私は新しい答えを投稿する代わりにコメントしたでしょうが、私はポイントが不足しています)
NSOrderedSet
の代わりにNSSet
を使用する必要がある場合は、次のコードを使用して、追加、挿入、およびNSMutableOrderedSet
メソッドを簡単に取得できるようにしています。オブジェクトを削除します。
@NSManaged private var myOrderedSet: NSOrderedSet
var myMutableOrderedSet: NSMutableOrderedSet {
return self.mutableOrderedSetValueForKey("myOrderedSet")
}