[英]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)")
}
}
})
我收到了一个错误
在闭包中引用属性mainContext需要显式self来使捕获语义显式化
我注意到一些解决方案,他们为块中的属性添加了self
。
这样做是好还是我们应该创建一个weak or unowned
以避免保留周期,以及处理这种情况的最佳方法是什么。
每次在块中使用self
时,必须考虑该块的未来,或者可以创建引用循环和泄漏内存(这就是Swift要求您明确的原因)。 当一个块捕获(保持一个强引用) self
,一些其他对象保持在该块上,并且self
保持在另一个对象上时,最常发生引用循环。 在该配置中,有一个包含self
和另一个对象的循环,因此都不能解除分配。
当块是“每次X发生时,请执行此操作”的处理程序时,通常会发生这种情况。 持有该块并执行通知的对象通常由想要通知的事物所拥有。 这可能是最常见的参考循环。 它通常通过self
弱化来解决。
然而, performBlock
不是这种功能。 它执行块然后释放它。 在Swift术语中它是@noescape
(并且在未来它可能被标记为这样,你不需要在noescape闭包中使用self.
)。 在块执行之前,不能释放self
,但是在块执行之后,循环立即被中断。 这可能正是你想要的。 所以使用self.
这里很好,没有理由添加弱引用的复杂性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.