我试图将我的tableView的数据源分成一个单独的委托对象。由于该代表需要在某个时候访问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'是'弱''
为了解决它,我要做以下操作:
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()方法中初始初始化代表,我没有创建强参考的危险,因为一旦我们离开范围,就会立即对实例进行交易的变量。该方法。或换句话说:我们唯一需要担心创建有力参考的变量(指向一类)的时间是,如果该变量是在类级别初始化的,那么只要班级就可以生存。
这是正确的吗?
请确认以下内容是否正确:通过在ViewDidload()方法中初始初始化代表,我没有创建强参考的危险,因为一旦我们离开范围,就会立即对实例进行交易的变量。该方法。
正确。一旦声明let
退出的范围,强有力的参考就会消失。
不幸的是,这意味着您的代表仍将被交易。您所做的就是让警告保持沉默。
基本上,您需要有很大的参考 ,否则它将立即消失。我的感觉是您应该在MyViewController
中进行参考。只要您的代表不包含对视图控制器的强大参考,就不会有强大的参考周期。如果您需要在代表中对MyViewController
的引用,请使其成为一个弱的,即视图控制器拥有代表,而不是代表拥有视图控制器。
对以下评论的回应:
我发现的几乎所有教程都将代表财产较弱,因此似乎是标准的做法。
是的,它是相当标准实践,包括可可中的例外。但是,在委派对象中对委托的弱参考是标准练习。在您的情况下,委派对象是 UITableView
而不是 MyViewController
。在Internet的第一个示例中,FileImporter
类似于代码中的UITableView
。在第二个示例中,DetailViewController
是委派对象。
如果考虑到它,则使用TableViewDelegate
来代替使MyViewController
符合协议。MyViewController
拥有代表是绝对有意义的。
这就是我解决这个问题的方式:
let dataSource = MyDataSource()
lazy var viewModel : MyViewModel = {
let viewModel = MyViewModel(dataSource: dataSource)
return viewModel
}()
,然后在ViewDidload()中:
tableView.delegate = self
tableView.dataSource = dataSource
您可以在此处查看完整的演示项目