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

Posted

技术标签:

【中文标题】在块、核心数据、swift中使用弱、强的自我使用【英文标题】:using weak, strong self usage in block, core data, swift 【发布时间】:2016-06-15 14:13:33 【问题描述】:

目前,我正在通过关注获取核心数据

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 以避免保留循环以及处理这种情况的最佳方法是什么。

【问题讨论】:

首先,Swift 3 的核心数据发生了很大的变化。鉴于您没有编写任何生产代码,我建议您学习它。其次,对自我的引用需要“自我”。在所有闭包中。 thanks.However,你能提供更多关于使用self的细节吗?它会导致内存泄漏吗? 这里的self 是什么(例如self.mainContext)?它是 UIKit 对象吗,比如 View Controller? @CouchDeveloper:Currenlty, self 是 NSObject 的子类 CoreDataStack。 从Core Data的角度来看,我对这段代码sn-p的目的有点困惑:如果selfCoreDataStack对象,那么一定有一些CoreDataStack方法可以执行第一条语句CoreDataStack.sharedIntance.backgroundContext.performBlock(...)。在 backgroundContext 中,您使用在 mainContext 中获取的 var result。从 backgroundContext 访问 result 无效 - 会崩溃。 【参考方案1】:

每次在块中使用self 时,都必须考虑该块的未来,否则您可能会创建引用循环并泄漏内存(这就是 Swift 要求您显式的原因)。当一个块捕获(持有对self 的强引用)、某个其他对象持有该块并且self 持有该其他对象时,最常发生引用循环。在该配置中,有一个包含self 和另一个对象的循环,因此两者都不能释放。

当块是“每次发生 X 时,请执行此操作”的处理程序时,最常发生这种情况。持有该块并执行通知的对象通常由想要被通知的事物所有。这可能是最常见的一种参考循环。一般通过将self弱化来解决。

performBlock,然而,不是这种功能。它执行块然后释放它。在 Swift 中,它是 @noescape (将来它可能会被标记为这样,你不需要在 noescape 闭包中使用 self. )。在块执行之前,self 不能被释放,但是在块执行之后,循环立即被打破。这可能正是你想要的。所以在这里使用self. 很好,没有理由增加弱引用的复杂性。

【讨论】:

以上是关于在块、核心数据、swift中使用弱、强的自我使用的主要内容,如果未能解决你的问题,请参考以下文章

用强弱自我打破保留周期

实现 API 时如何避免在块中捕获自我?

在块中修改后未更新 Swift 结构

如何在作为协议类型的 Swift 通用数据结构中使用弱引用?

在嵌套块中引用弱自我

闭包中的弱自我和后果示例