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

时间:2016-06-15 14:13:34

标签: ios objective-c memory-management swift2 weak-references

目前,我正在按照

进行核心数据的提取
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)")
        }
    }
})

我收到了错误

  

在闭包中引用属性mainContext需要显式的self to   使捕获语义显式化

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

这样做是否合适,或者我们是否应该创建weak or unowned以避免保留周期,以及处理这种情况的最佳方法是什么。

1 个答案:

答案 0 :(得分:3)

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

这通常发生在块是&#34的处理程序时;每次X发生时,请执行此操作。"持有该块并执行通知的对象通常由想要通知的事物所拥有。这可能是最常见的参考循环。通常通过使self弱化来解决。

然而,

performBlock不是这种功能。它执行块然后释放它。在Swift术语中,它是@noescape(并且将来可能会标记为这样,并且您不需要在noescape闭包中使用self.)。在块执行之前,self无法解除分配,但在块执行后,循环立即被中断。这可能正是你想要的。所以在这里使用self.很好,并且没有理由添加弱引用的复杂性。