通过 Swift 中的不同类调用委托方法
Posted
技术标签:
【中文标题】通过 Swift 中的不同类调用委托方法【英文标题】:Calling delegate method through different classes in Swift 【发布时间】:2017-08-21 13:22:37 【问题描述】:我正在获取 JSON 菜单,一旦 JSON 返回,我想在 SomeTableViewController 类中运行 menuReady() 以更新表格的内容。但是下面的代码似乎不起作用。
AIM:在 JSON 返回后运行 menuReady() 以更新内容。
问题: menuReady() 永远不会被触发。
SomeTableViewController.swift
class SomeTableViewController: UITableViewController, MenuModelDelegate
override func viewDidLoad()
menuModel.delegate = self
func menuReady()
// This is NOT fired.
print("SomeViewController.menuReady()")
MenuModel.swift
protocol MenuModelDelegate : class
func menuReady()
class MenuModel: NSObject
var delegate:MenuModelDelegate?
func getMenu(data: JSON)
// This is fired.
print("MenuModel.getMenu()")
delegate?.menuReady()
点击按钮时从 AnotherViewController 调用
AnotherViewController.swift
class AnotherViewController : UIViewController
func buttonTapped(sender: UIButton!)
// This function is fired.
// jsonData is some json data returned from http request
let menuModel = MenuModel()
menuModel.getMenu(data: jsonData)
【问题讨论】:
SomeTableViewController
中的menuModel
和“其他类”中的menuModel
是完全相同的对象吗?
@PhillipMills 不,它们在单独的对象中。三个不同的对象。
那么,您授予委托的MenuModel
对象与您调用委托方法的对象不相同?
@PhillipMills 他们不一样。
你在哪里调用getMenu(data: JSON)
方法?我假设您必须在代码中的某个地方调用它来触发委托...
【参考方案1】:
委托方法旨在以“一对一”的关系工作,因为您在不同的地方有多个不同的MenuModel
实例,因此您在此处尝试实现的目标将不起作用。您应该尝试将MenuModel
初始化为SomeTableViewController
的属性,然后像下面这样使用它:
class SomeTableViewController: UITableViewController, MenuModelDelegate
private let menuModel: MenuModel = MenuModel()
override func viewDidLoad()
self.menuModel.delegate = self
self.menuModel.getMenu(data: jsonData)
func menuReady()
print("SomeTableViewController.menuReady()")
如果您正在寻找可以更新多个视图控制器的解决方案,那么更好的解决方案是阅读NotificationCenter
。使用通知,您可以将观察者添加到多个视图控制器/类,并简单地让您的MenuModel
发布通知。
https://developer.apple.com/documentation/foundation/notificationcenter
希望对你有帮助。
【讨论】:
【参考方案2】:感谢@PhillipMills 指出委托对象应该属于同一个对象实例。
这是解决问题的方法。现在委托函数可以正常工作了。
SomeTableViewController.swift
class SomeTableViewController: UITableViewController, MenuModelDelegate
private let menuModel: MenuModel = MenuModel() // <--- Added property
override func viewDidLoad()
menuModel.delegate = self
func menuReady()
print("menuReady")
// <--- Added Function
func getModel() -> MenuModel
return self.menuModel
MenuModel.swift
protocol MenuModelDelegate : class
func menuReady()
func getModel() -> MenuModel
class MenuModel: NSObject
var delegate:MenuModelDelegate?
func getMenu(data: JSON)
print("getMenu()")
delegate?.menuReady()
AnotherViewController.swift
class AnotherViewController : UIViewController
func buttonTapped(sender: UIButton!)
// jsonData is some json data returned from http request
// let menuModel = MenuModel() <--- Removed line
/* You need to find a way to pass in someTableViewController
* Use the menuModel defined in SomeTableViewController to
* Call menuModel.getMenu() instead of defining a new menuModel */
let menuModel = someTableViewController.getModel()
menuModel.getMenu(data: jsonData)
【讨论】:
以上是关于通过 Swift 中的不同类调用委托方法的主要内容,如果未能解决你的问题,请参考以下文章