在块中使用弱、强自我使用,核心数据,swift

using weak, strong self usage in block, core data, swift

目前,我正在通过以下方式获取核心数据

CoreDataStack.sharedIntance.backgroundContext.performBlock({
    let fetchRequest                =   NSFetchRequest(entityName: "Schedule")
    let sortDescriptor              =   NSSortDescriptor(key: "startTime", ascending: true)

    fetchRequest.sortDescriptors    =   [sortDescriptor]
    var result  =   [Schedule]()

    mainContext.performBlockAndWait { [unowned self] in
        do {
            result = try mainContext.executeFetchRequest(fetchRequest) as! [Schedule]
            success?(result)
        } catch {
            print("error is \(error)")
        }
    }
})

我收到一个错误

Reference to property mainContext in closure requires explicit self to make capture semantics explicit

我注意到一些解决方案,它们为块中的 属性 添加了 self

这样做好还是我们应该创建一个 weak or unowned 来避免保留循环以及处理这种情况的最佳方法是什么。

每次在块中使用 self 时,您必须考虑该块的未来,否则您可以创建引用循环和泄漏内存(这就是为什么 Swift 要求您明确).当一个块捕获(持有对 self 的强引用)时,引用循环最常发生,其他一些对象持有该块,并且 self 持有另一个对象。在该配置中,有一个包含 self 和另一个对象的循环,因此两者都不能解除分配。

当块是 "every time X happens, please do this." 的处理程序时最常发生这种情况持有该块并执行通知的对象通常由想要通知的对象拥有。这可能是最常见的一种参考循环。一般通过使 self weak.

来解决

performBlock,然而,并不是这种函数。它执行块然后释放它。在 Swift 术语中它是 @noescape (将来它可能会被标记为这种方式,您将不需要在 noescape 闭包中使用 self. )。在块执行之前,self不能被释放,但是在块执行之后,循环立即被打破。这可能正是您想要的。所以这里用self.就可以了,没必要再增加弱引用的复杂度