NSTableView调用.reloadData()时Delegate方法未触发问题排查
嘿,我之前也踩过几乎一模一样的坑!这种没编译报错但就是不干活的问题最磨人了,咱们一步步来排查:
先死磕Delegate/DataSource的关联
别只盯着IBOutlet的tableView变量是否连上,这俩才是关键:- 要么在Storyboard/XIB里,把tableView的
delegate和dataSource拖到你的VC实例上; - 要么在代码里手动绑定:
tableView.delegate = self、tableView.dataSource = self。
我之前就是在XIB里漏拖了delegate,IBOutlet显示正常,但就是没触发任何代理方法,蠢到拍大腿。
- 要么在Storyboard/XIB里,把tableView的
检查VC的初始化与生命周期
会不会你的第四个VC初始化方式有问题?比如直接用init()创建而不是从Storyboard/XIB加载,导致IBOutlet根本没被初始化?可以在viewDidLoad里加个打印:print(tableView),如果输出是nil,那调用reloadData()等于白忙活。确认代理方法的拼写完全正确
别把NSTableView和UITableView的方法搞混!比如NSTableView的数据源方法是numberOfRows(in tableView: NSTableView),不是UITableView的tableView(_:numberOfRowsInSection:)。Swift的类型推断有时候不会报错,但就是不执行方法。可以用Xcode的自动补全(Cmd+Shift+O搜方法名)确保拼写、参数完全一致,或者给方法加个@objc标记试试。排查是否有其他对象抢占了Delegate
会不会在某个工具类、或者VC的其他方法里,不小心把tableView.delegate设成了别的对象?可以在调用reloadData()之前加个打印:print(tableView.delegate),看看是不是指向你的VC实例。强制在主线程刷新
如果你是在后台线程(比如网络请求回调)里调用的reloadData(),UI操作必须切回主线程!试试把刷新代码包在:DispatchQueue.main.async { self.tableView.reloadData() }我之前就是在异步回调里直接调用,结果没反应,切主线程立刻就正常了。
终极杀招:清理缓存重启Xcode
有时候Xcode的缓存会抽风,IBOutlet或代理关联看似正常实则失效。试试Clean Build Folder(Cmd+Shift+K),然后重启Xcode,再重新关联一次IBOutlet和delegate/dataSource。
内容的提问来源于stack exchange,提问作者Greg Steiner

