目前,我正在按照
进行核心数据的提取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
以避免保留周期,以及处理这种情况的最佳方法是什么。
答案 0 :(得分:3)
每次在块中使用self
时,必须考虑该块的未来,或者可以创建引用循环和泄漏内存(这就是Swift要求您明确的原因)。当块捕获(保持强引用)self
,其他一些对象保持在该块上,并且self
保持在该另一个对象上时,通常会发生引用循环。在该配置中,有一个包含self
和另一个对象的循环,因此都不能解除分配。
这通常发生在块是&#34的处理程序时;每次X发生时,请执行此操作。"持有该块并执行通知的对象通常由想要通知的事物所拥有。这可能是最常见的参考循环。通常通过使self
弱化来解决。
performBlock
不是这种功能。它执行块然后释放它。在Swift术语中,它是@noescape
(并且将来可能会标记为这样,并且您不需要在noescape闭包中使用self.
)。在块执行之前,self
无法解除分配,但在块执行后,循环立即被中断。这可能正是你想要的。所以在这里使用self.
很好,并且没有理由添加弱引用的复杂性。