代码之家  ›  专栏  ›  技术社区  ›  Sjakelien

可选委托方法非可选

  •  1
  • Sjakelien  · 技术社区  · 6 年前

    我有这个班 apiHandler 使用以下委托方法:

    @objc protocol apiHandlerDelegate: class {
        @objc optional func didGetMessages(_ sender:apiHandler)
        @objc optional func didGetEvents(_ sender:apiHandler)
        @objc optional func didLogin(success:Bool, sender:apiHandler)
    }
    

    我的一个 viewControllers 取决于 didGetEvents 我也是

    class myViewController: UIViewController, apiHandlerDelegate
    

    现在,不知怎么的,在 myViewController ,我还需要实现

    func didLogin(success: Bool, sender: apiHandler) {
        // do nothing
    }
    

    否则应用程序将崩溃,返回

    [我的应用程序。myViewController didloginwhithsuccess:发件人:]:无法识别 选择器发送到实例0x7f90ac01b410'

    我是否误解了可选部分?我希望能够实现viewController所需的委托方法

    编辑//////

    因此,在我的apiHandler中,我进行一个REST调用,在completion块中,我调用didLogin,如下所示:

    let urlString = String(format:"%@/api/sessions/current", baseUrl)
                        Alamofire.request(urlString, headers: headers)
                            .responseJSON { response in
                                self.Login(completion: { (success) in
                                    self.delegate?.didLogin!(success: success, sender: self)
                                    completion(true)
                                })
                        }
    

    重要的是: (一) didGetMessages消息 教训事件 有选择地执行,即我不需要在viewControllers中实现它们,viewControllers是apiHandler的委托 2)didLogin需要实现,否则应用程序崩溃

    1)和2)之间的主要区别在于didLogin有一个完成块。我需要在ViewControllers中有布尔值

    4 回复  |  直到 6 年前
        1
  •  2
  •   Nikdemm    6 年前

    我想如果你打电话 didLoginWithSuccess 从用于可选功能的Swift代码中,您需要使用可选链接:

    apiHandler.didLoginWithSuccess?()
    

    如果你打电话 没有成功的didloginw 在Objective-C代码中,需要检查给定选择器的is object response:

    if ([apiHandler respondsToSelector:@selector(didLoginWithSuccess:)])
    {
        // then call func
    }
    
        2
  •  2
  •   OOPer    6 年前

    您可能需要更改此行:

    self.delegate?.didLogin!(success: success, sender: self)
    

    致:

    self.delegate?.didLogin?(success: success, sender: self)
    
        3
  •  1
  •   Jacob Jidell    6 年前

    无需任何objectiveC代码,您可以通过执行以下操作轻松将其设置为可选:

    protocol apiHandlerDelegate: class {
        func didGetMessages(_ sender:apiHandler)
        func didGetEvents(_ sender:apiHandler)
        func didLogin(success:Bool, sender:apiHandler)
    }
    
    extension apiHandlerDelegate {
        func didGetMessages(_ sender:apiHandler) { } // Empty implementation to make it optional
        func didGetEvents(_ sender:apiHandler) { } // Empty implementation to make it optional
        func didLogin(success:Bool, sender:apiHandler) { } // Empty implementation to make it optional
    }
    

    有关详细信息,请查看此链接: https://medium.com/@ant_one/how-to-have-optional-methods-in-protocol-in-pure-swift-without-using-objc-53151cddf4ce

        4
  •  1
  •   Caleb    6 年前

    我是否误解了可选部分?我希望能够实现viewController所需的委托方法

    因为它涉及到协议, optional 只是意味着编译器不会坚持让采用协议的类实现这些方法。相反,如果未能实现标记为 required .

    但是,如果代码试图调用 可选择的 方法,您将看到未实现的选择器运行时错误。如果您使用 可选择的 方法,在调用对象之前,应检查该对象是否实现了该方法,例如:

    if someObject.responds(to:Selector("didLoginSuccess:sender:") {
        someObject.didLogin(success:... sender:...)
    }
    

    换句话说,编译器不会阻止您 打电话 一个可选的方法,由你来确保你所调用的可选方法实际存在。