2017-08-21 37 views
0

我正在抓取JSON菜单,并且一旦JSON返回,我想运行menuReady()更新SomeTableViewController类中表的内容。但是下面的代码似乎不起作用。通过Swift中的不同类调用委托方法

AIM:运行menuReady()一旦返回JSON就更新内容。

问题: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) 
    } 
} 
+1

是'menuModel'在'SomeTableViewController'和'menuModel'在 “其他一些类” 完全相同的对象? –

+0

@PhillipMills不,他们是分开的对象。三个不同的对象。 –

+0

所以,你给委托给的'MenuModel'对象是**不是**和你调用委托方法的那个一样吗? –

回答

3

委托方法被设计在其中工作了“一对一”的关系,你想在这里实现什么,你有多个将无法正常工作不同地方的MenuModel的不同实例。你应该尝试初始化MenuModelSomeTableViewController属性,并使用它像下面这样:

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

我希望帮助。

0

感谢@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。迅速

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) 
    } 
}