NSMangedObject
をデータベースから削除すると、割り当てられたローカル変数はどうなりますか?削除されたNSManagedObjectsへの参照を格納するローカル変数に何が起こるか
例えば、私はシンプルNSManagedObject持っている:
class MyManagedObject: NSManagedObject {
@NSManaged var name: String
}
をそして、私のViewControllerに、私はデータベースから引き出し、それをローカルに割り当てます
class ViewController: UIViewController {
var myManagedObject: MyManagedObject!
}
その後、私はそれを削除データベースから。
印刷する場合は、オブジェクト名のオブジェクトが存在しないかのように私は、コンソール
print("myManagedObject.name = \(myManagedObject.name)")
//prints: "myManagedObject.name = "
に次のように取得しますか?しかし、変数をオプションにしてnilをチェックすると、それはゼロでないと言われます。
私はこれを私の心の中でどうやって調和させるかについてはあまりよく分かりません。ローカル変数を指す何かがあるようですが、そのプロパティはなくなりました。
そのオブジェクトにそのオブジェクトのプロパティに依存する多くの異なるUIオブジェクトがある場合、そのオブジェクトのローカルディープコピーがメモリにあると想定できません。ここで
は、より完全なコードです:
のviewDidLoadで、私はそれをローカルに割り当て、その後、新しいオブジェクトを作成し、コンテキストを保存し、オブジェクトをフェッチします。今、私はデータベースから削除し、そう
print("The object's name is: \(myManagedObject.name)")
//prints: The object's name is: My First Managed Object
::私はローカル変数のname
プロパティを印刷する場合は、この時点で
class ViewController: UIViewController {
var myManagedObject: MyManagedObject!
override func viewDidLoad() {
super.viewDidLoad()
//1 Create the new object
let newObject = NSEntityDescription.insertNewObject(forEntityName: "MyManagedObject", into: coreDataManager.mainContext) as! MyManagedObject
newObject.name = "My First Managed Object"
//2 Save it into the context
do {
try coreDataManager.mainContext.save()
} catch {
//handle error
}
//3 Fetch it from the database
let request = NSFetchRequest<MyManagedObject>(entityName: "MyManagedObject")
do {
let saved = try coreDataManager.mainContext.fetch(request)
//4 Store it in a local variable
self.myManagedObject = saved.first
} catch {
//handle errors
}
}
}
が、私は正しい応答を得る
if let storedObject = myManagedObject {
coreDataManager.mainContext.delete(storedObject)
do {
try coreDataManager.mainContext.save()
} catch {
//handle error
}
}
しかし、今、私が印刷すると、最も奇妙な結果を得ます:
print("myManagedObject.name = \(myManagedObject.name)")
//prints: "myManagedObject.name = "
これはまったく私がメモリが動作することを期待している方法ではありません。クラスFoo
のインスタンスを作成し、そのインスタンスを別のオブジェクトに渡すと、同じインスタンスになります。それは誰もそれを指していないと消えるだけです。
この場合---変数は何ですか、myManagedObject
? nil
ではありません。文字列は何ですか、name
?それは空文字列ですか?それとも他の奇妙なメタタイプですか?
ローカルに「割り当てる」コードを表示します。 var myManagedObject:MyManagedObject!あなたの質問の更新のためにMyManagedObject – Retterdesdialogs
タイプの新しい変数を "作成"するだけです。管理対象オブジェクトを削除した後、削除済みとしてマークし、データベースを保存した後、データベースから削除します。管理対象オブジェクトでは、isDeletedプロパティまたは "fault"プロパティをチェックする必要があります。オブジェクトは予測どおりにオブジェクトを保持しますが、その動作は予測できません。フレームワークの変更に応じて何かが起きる可能性があり、空の文字列はそれがうまくいくための素晴らしい回避策のようです。このオブジェクトが削除された後にこのオブジェクトを使用しないことは、あなたの仕事です。 –
しかし、ウサギの穴は深くなります。複数のコンテキストを使用し、あるコンテキストでオブジェクトを削除すると、そのオブジェクトは他のコンテキストにも存在します。しかし、第2の状況で変更を適用しようとすると、解決する必要がある競合が報告されます。したがって、メモリ内では、コンテキストごとに1つのインスタンスがあり、ARCルールが割り当てを解除するまで、これらのインスタンスはメモリ内に保持されます。しかし、そのプロパティはいつでも変更することができます。オブジェクトはまだ存在しますが、そのプロパティにはアクセスできません。あらゆる権利によってクラッシュするはずですが、例外が処理されたようです。 –