3

tableView のデータソースを別のデリゲート オブジェクトに分離しようとしています。そのデリゲートはある時点でテーブルビューにアクセスする必要があるため、デリゲート内の委任オブジェクトへの参照が必要です。どちらもクラスなので、デリゲートを作成して強い参照サイクルを回避する必要があります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
    }
}

デリゲート Xcode をインスタンス化しようとすると、「プロパティ 'tableViewDelegate' が 'weak' であるため、インスタンスはすぐに割り当て解除されます」という警告がスローされます。

したがって、それを修正するために、次のことを行います。

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() メソッドでデリゲートを初期化することにより、そのインスタンスを保持する変数がそのメソッドのスコープを離れるとすぐに割り当て解除されるため、強い参照を作成する危険はありません。別の言い方をすれば、(クラスを指す) 変数が強い参照を作成することについて心配する必要があるのは、変数がクラス レベルで初期化されている場合のみであり、そのため、クラスが存続する限り存続します。 .

あれは正しいですか?

4

2 に答える 2

0

これが私がこの問題を解決した方法です:

    let dataSource = MyDataSource()

    lazy var viewModel : MyViewModel = {
        let viewModel = MyViewModel(dataSource: dataSource)
        return viewModel
    }()

そしてviewDidLoad()で:

    tableView.delegate = self
    tableView.dataSource = dataSource

ここで完全なデモ プロジェクトを確認できます。

于 2019-10-14T14:22:59.950 に答える