swift - 如何在不触发 "Instance will be immediately deallocated because property ' 的情况下实例化弱委托(delegate) tableViewDelegate' is 'weak' "

标签 swift delegates weak

我正在尝试将 tableView 的数据源分离到一个单独的委托(delegate)对象中。由于该委托(delegate)需要在某个时候访问 TableView ,因此我需要引用委托(delegate)中的委托(delegate)对象;由于两者都是类,我需要通过使委托(delegate) weak

来避免强引用循环

为此,我尝试了以下代码。

class MyViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    weak var tableViewDelegate: UITableViewDataSource?

    override func viewDidLoad() {
        super.viewDidLoad()
        tableViewDelegate = TableViewDelegate() // throwing a warning
        tableView.dataSource = tableViewDelegate
    }
}

当我尝试实例化委托(delegate)时,Xcode 抛出警告:“实例将立即释放,因为属性‘tableViewDelegate’是‘弱’”

因此,为了修复它,我执行以下操作:

class MyViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    weak var tableViewDelegate: UITableViewDataSource?

    override func viewDidLoad() {
        super.viewDidLoad()
        let delegate = TableViewDelegate() // worried this creates a strong reference.
        self.tableViewDelegate = delegate
        tableView.dataSource = delegate
    }
}

请确认以下内容是否正确:通过在 viewDidLoad() 方法中初始化委托(delegate),我没有创建强引用的危险,因为一旦我们离开范围,保存该实例的变量就会被释放那个方法。或者换句话说:我们唯一需要担心变量(指向类)创建强引用的情况是变量是否在类级别初始化,因此只要类存在就会存在.

对吗?

最佳答案

Please confirm if the following is true or not: by initialising the delegate in the viewDidLoad() method I am not in danger of creating a strong reference because the variable that holds that instance is deallocated as soon as we leave the scope of that method.

正确。一旦声明 let 的范围退出,强引用就会消失。

不幸的是,这意味着您的委托(delegate)仍将被释放。您所做的只是让警告静音。

基本上,您需要在某处 对委托(delegate)有一个强引用,否则它会立即消失。我的感觉是您应该使 MyViewController 中的引用变得强大。只要您的委托(delegate)不包含对 View Controller 的强引用,就不会有强引用循环。如果您需要在委托(delegate)中引用 MyViewController,请将其设为弱引用,即 View Controller 拥有委托(delegate),而不是委托(delegate)拥有 View Controller 。


回复以下评论:

almost all the tutorials I have found have the delegate property as weak, so it seems standard practice.

是的,这是公平的标准做法,也有异常(exception),包括在 Cocoa 中。但是,在委托(delegate)对象中弱引用委托(delegate)是标准做法。在您的情况下,委托(delegate)对象是 UITableView 而不是 MyViewController。在您来自 Internet 的第一个示例中,FileImporter 类似于代码中的 UITableView。在第二个示例中,DetailViewController 是委托(delegate)对象。

如果您考虑一下,您的 TableViewDelegate 被用来代替使 MyViewController 符合协议(protocol)。 MyViewController 拥有委托(delegate)是绝对合理的。

关于swift - 如何在不触发 "Instance will be immediately deallocated because property ' 的情况下实例化弱委托(delegate) tableViewDelegate' is 'weak' ",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54956878/

相关文章:

swift - 是否有任何变通方法可以在 swift 中指定内部函数捕获列表及其修饰符

javascript - 为什么 window.close 不适用于多个窗口

swift - 类型 'Any' 没有下标成员

ios - 在没有segue的情况下在两个 View Controller 之间传递数据?

ios - 使用委托(delegate)模式的选择器无效

c - 用 weak 属性在 c 中编写测试代码是不好的做法吗?

automatic-ref-counting - ARC项目中用于NSTextView的IBOutlet

ios - Swift/iOS - 当设备恢复在线时将离线核心数据与服务器同步

ios - 表格 View 未快速加载

ios - 委托(delegate)和回调不适用于传递模型数据