Delegate在类间传递时变为nil,代理接收用户数据为空
问题排查:代理传递数据始终为nil的原因及修复
核心问题分析
你的代码存在三个关键错误,直接导致代理无法正常传递数据:
1. 代理对象未建立有效关联
HomePageViewController中声明的loginview: LoginViewController?从未被初始化,始终为nil。因此loginview?.userdelegate = self通过可选链调用直接跳过,根本没有完成代理绑定。
2. 跳转与代理设置顺序完全颠倒
在LoginViewController的loginRequestrd方法中,你直接创建并push了全新的HomePageViewController实例,但这个新实例和当前LoginViewController没有任何代理关联。正确逻辑应该是先给即将跳转的HomeVC设置代理,再执行跳转。
3. 冗余且逻辑错误的方法调用
HomePageViewController的viewDidLoad中调用loginview?.loginRequestrd()完全不合理,登录请求应该由LoginViewController自身触发(比如用户点击登录按钮),而非后续页面反向调用。
修正后的代码示例
1. 修正LoginViewController的跳转逻辑
protocol UserDetailsDelegate: AnyObject { func didSendUserDetails(_ object: LoginViewController) } class LoginViewController: UIViewController { var details: LoginDetails? var userdelegate: UserDetailsDelegate? func loginRequestrd() { // 原有数据解析代码保持不变 guard let logdetails = try? JSONDecoder().decode(LoginDetails.self, from: data) else { return } self.details = LoginDetails(status: logdetails.status, message: logdetails.message, id: logdetails.id, username: logdetails.username, email: logdetails.email, fullname: logdetails.fullname, ava: logdetails.ava) // 先创建目标页面实例 let homeVC = HomePageViewController() // 建立代理关联 self.userdelegate = homeVC // 发送数据 self.didSendUserData() // 再执行跳转 DispatchQueue.main.async { self.navigationController?.pushViewController(homeVC, animated: true ) } } func didSendUserData () { guard let userdetails = details else { return } userdelegate?.didSendUserDetails(self) } }
2. 修正HomePageViewController的冗余代码
class HomePageViewController: UITabBarController { var userdetails: LoginDetails? var posttitle: String? override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground UITabBar.appearance().barTintColor = .systemBackground tabBar.tintColor = .label DispatchQueue.main.async { self.setupVCs() } // 移除原有的loginview相关无效代码 } } extension HomePageViewController: UserDetailsDelegate { func didSendUserDetails(_ object: LoginViewController) { self.userdetails = object.details } }
额外优化建议(遵循Swift规范)
- 类型名大驼峰:将
userDetailsDelegate改为UserDetailsDelegate,loginDetails改为LoginDetails,符合Swift命名规范,避免与实例变量混淆。 - 代理方法直接传数据:无需传递整个ViewController,直接传递
LoginDetails实例更符合委托模式的单一职责:// 修改协议 protocol UserDetailsDelegate: AnyObject { func didSendUserDetails(_ details: LoginDetails) } // LoginViewController中调用方法 func didSendUserData () { guard let userdetails = details else { return } userdelegate?.didSendUserDetails(userdetails) } // HomePageViewController中实现方法 extension HomePageViewController: UserDetailsDelegate { func didSendUserDetails(_ details: LoginDetails) { self.userdetails = details } }
内容的提问来源于stack exchange,提问作者Michael Drammond
相关产品推荐
相关产品推荐

