Swift-MVP问题:Presenter代理方法未调用,求排查原因
你遇到的问题是AddressDemoPresenter扩展中的addressDemoViewControllerDidTap方法未被触发,核心原因是Presenter实例被提前释放,导致ViewController的delegate变为nil。
问题分析
在你的代码中,当调用makeAddressDemoViewController()方法时,内部创建的AddressDemoPresenter实例如果没有被外部强引用持有,方法执行完成后这个实例就会被ARC自动释放。而ViewController的delegate是weak修饰的,不会持有Presenter,所以此时VC的delegate会变成nil,点击按钮时delegate?.addressDemoViewControllerDidTap(self)这行代码相当于空操作,不会触发代理方法。
比如如果外部代码是这样写的:
let nav = AddressDemoPresenter().makeAddressDemoViewController() // 这里Presenter实例创建后立即被释放,没有任何强引用持有它
这种情况下就会出现你遇到的问题。
修复方案
确保AddressDemoPresenter实例被外部强引用持有,而不是临时创建后就丢弃。
举个例子,在需要展示这个导航控制器的父控制器中,持有Presenter的强引用:
class ParentViewController: UIViewController { // 强引用持有Presenter private var addressPresenter: AddressDemoPresenter! override func viewDidLoad() { super.viewDidLoad() addressPresenter = AddressDemoPresenter() let navController = addressPresenter.makeAddressDemoViewController() // 将导航控制器添加到当前视图层级 addChild(navController) navController.view.frame = view.bounds view.addSubview(navController.view) navController.didMove(toParent: self) } }
这样Presenter实例会被addressPresenter这个强引用变量持有,生命周期和父控制器一致,ViewController的delegate就能保持有效,点击按钮时就能正常触发addressDemoViewControllerDidTap方法。
额外检查
另外可以确认按钮的点击逻辑是否正常:你的buttonTapped方法是@objc修饰的,且按钮的addTarget绑定正确,这部分代码没有问题,所以核心问题还是Presenter的生命周期。
内容的提问来源于stack exchange,提问作者user19344300

