我试图将tableView的数据源分离为单独的委托对象。由于该委托需要在某个时刻访问表视图,因此我需要引用该委托中的委托对象。并且由于两者都是类,因此我需要通过使委托JSON.parse()
为此,我尝试了以下代码。
weak
当我尝试实例化委托Xcode时,抛出警告:“由于属性'tableViewDelegate'为'弱',实例将被立即释放”
要解决此问题,请执行以下操作:
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
}
}
请确认以下条件是否成立:通过在viewDidLoad()方法中初始化委托,我没有创建强引用的危险,因为保存该实例的变量会在我们离开范围时立即被释放。该方法。或换一种说法:我们唯一需要担心的是变量(指向类)创建强引用的唯一原因是,该变量是否在类级别上初始化,因此将在该类存在的情况下持续存在。
对吗?
答案 0 :(得分:2)
请确认以下条件是否成立:通过在viewDidLoad()方法中初始化委托,我没有创建强引用的危险,因为保存该实例的变量会在我们离开范围时立即被释放。该方法。
正确。一旦声明let
的范围退出,强引用就会消失。
不幸的是,这意味着您的代表仍将被释放。您所要做的就是使警告静音。
基本上,您需要对委托 somewhere 进行强有力的引用,否则它将立即消失。我的感觉是,您应该使MyViewController
中的引用更强。只要您的委托不包含对视图控制器的强引用,就不会有强引用周期。如果您需要在委托中引用MyViewController
,请使它成为一个弱者,即视图控制器拥有委托,而不是委托拥有视图控制器。
回复以下评论:
我发现的几乎所有教程的委托属性都很弱,因此这似乎是标准做法。
是的,这是相当的标准惯例,可可中也有例外。但是,通常的做法是在委托对象中对委托的引用很少。在您的情况下,委派对象是UITableView
,而不是MyViewController
。在您的第一个Internet示例中,FileImporter
与代码中的UITableView
类似。在第二个示例中,DetailViewController
是委派对象。
如果考虑一下,将使用TableViewDelegate
来代替MyViewController
遵守协议。 MyViewController
拥有委托是绝对合理的。
答案 1 :(得分:0)
这是我解决此问题的方法:
let dataSource = MyDataSource()
lazy var viewModel : MyViewModel = {
let viewModel = MyViewModel(dataSource: dataSource)
return viewModel
}()
,然后在viewDidLoad()中:
tableView.delegate = self
tableView.dataSource = dataSource
您可以看到完整的演示项目here