【问题标题】:Calling delegate method through different classes in Swift通过 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)方法?我假设您必须在代码中的某个地方调用它来触发委托...

标签: ios swift delegates programmatically


【解决方案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)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-23
      相关资源
      最近更新 更多