gpt4 book ai didi

swift - NSManagedObjectContext 释放问题 - (Swift | Associated Objects)

转载 作者:搜寻专家 更新时间:2023-11-01 05:36:25 24 4
gpt4 key购买 nike

我希望有人能解释为什么在解除分配源/主机对象时,以下示例中的关联对象不会自动解除分配。下面的示例代码有些做作(提前致歉),但它解释了我的问题。


该示例假设一个 CoreData 实体 Product 具有字符串属性 sku 和 Xcode 模板提供的默认 CoreData 堆栈:

import UIKit
import CoreData

class ViewController: UIViewController {

@IBAction func createProduct(sender: AnyObject) {

let context = CoreDataHelpers.vendBackgroundWorkerContext()
let newProduct = CoreDataHelpers.newProduct(context: context)

newProduct.sku = "8-084220001"

do {
try newProduct.managedObjectContext?.save()
print("Product created [SKU: \(newProduct.sku ?? "NotDefined")]")
} catch {
print(error)
}
}
}


public class CoreDataHelpers {

public static let mainContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext

public class func vendBackgroundWorkerContext() -> NSManagedObjectContext {
let managedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
managedObjectContext.parentContext = self.mainContext

return managedObjectContext
}

class func newProduct(context context: NSManagedObjectContext) -> Product {
let newProduct = NSEntityDescription.insertNewObjectForEntityForName("Product", inManagedObjectContext: context) as! Product

return newProduct
}

}

当执行 createProduct 函数时,新的 PrivateQueueConcurrencyType Managed Object Context (MOC) 将被出售并由新的 Product Managed Object (MO) 使用。到目前为止,上面的代码工作正常。

但是!如果我组合 createProduct 函数的前两行,这样:

let newProduct = CoreDataHelpers.newProduct(context: CoreDataHelpers.vendBackgroundWorkerContext())

然后应用程序将在 try newProduct.managedObjectContext?.save()EXC_BAD_ACCESS 处崩溃。

乍一看,这有点奇怪——因为我们所做的只是重构了代码。深入研究 documentation , managedObjectContext 属性声明为 unowned(unsafe)。这可能意味着创建的 MOC 已被释放,我们有一个悬挂指针(如果我的假设有误,请纠正我)。

为了确保 MOC 不会被释放,我尝试将它与 MO 本身相关联。 新产品:

class func newProduct(context context: NSManagedObjectContext) -> Product {
let newProduct = NSEntityDescription.insertNewObjectForEntityForName("Product", inManagedObjectContext: context) as! Product

var key: UInt8 = 0
objc_setAssociatedObject(newProduct, &key, context, .OBJC_ASSOCIATION_RETAIN)

return newProduct
}

这似乎非常有效 - 直到我 checkin Instruments。看起来当 Product MO 被释放时,现在关联的 MOC 不是(它不应该在源对象被释放时自动释放吗?)

我的问题是:有人可以解释对阻止它被释放的 MOC 的附加引用在哪里吗?我是否在 MO 和 MOC 之间创建了一个保留周期?

enter image description here

最佳答案

您可能正在创建循环所有权(保留循环)。

每个托管对象都由托管上下文拥有(上下文拥有对象),将上下文设置为关联对象意味着对象现在也拥有上下文。

因此,它们不会被释放。

真正的解决方案是将背景上下文保存到本地属性,就像您对 mainContext 所做的一样。

关于swift - NSManagedObjectContext 释放问题 - (Swift | Associated Objects),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38388470/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com