我们为什么以及何时应该使用可选功能(在Swift中)?

时间:2016-06-22 02:26:11

标签: swift

我有关于可选功能的以下问题:

@objc protocol SSRadioButtonControllerDelegate {
/**
    This function is called when a button is selected. If 'shouldLetDeSelect' is true, and a button is deselected, this function
is called with a nil.

*/
optional func didSelectButton(aButton: UIButton?)
}
  1. 什么是可选功能?为什么不必声明方法?它的用途是什么?
  2. 为什么@objc协议代替@protocol

4 个答案:

答案 0 :(得分:1)

协议告诉代表您已选择UIButton。

此协议的可选方法通知代表是否可以选择按钮。

如果我们想在Swift协议中使用可选方法,我们使用 @objc 属性。

@objc protocol SSRadioButtonControllerDelegate: class {
optional func shouldLetDeSelect(sender: SSRadioButtonController) -> Bool
func didSelectButton(sender: UIButton?)
}

这也意味着Swift结构或枚举不能再采用此协议。但这并不重要,因为你已经把它作为一个类协议。

@objc属性似乎不是Swift-y。因此,当我们认为我们需要Swift协议中的可选方法时,我们的替代方案是什么?

将可选方法移至单独的协议:

protocol SSRadioButtonControllerDelegate: class {
func shouldLetDeSelect(sender: SSRadioButtonController) -> Bool
}

然后,您可以选择在主视图控制器中采用并实现此新的委托方法。

controller.delegate = self
// Uncomment if we need to implement shouldLetDeSelect:
// controller.ButtonSelectionDelegate = self

另一种方法是为扩展中的“可选”方法提供默认实现。我们可以通过删除@objc和可选属性来清理协议定义:

protocol SSRadioButtonControllerDelegate: class {
func shouldLetDeSelect(sender: SSRadioButtonController) -> Bool
func didSelectButton(sender: UIButton?)
}

该方法现在是强制性的,必须在某处实施。

extension SSRadioButtonControllerDelegate {
func shouldLetDeSelect(sender: SSRadioButtonController) -> Bool {
return true
}
}

答案 1 :(得分:0)

当您在此条件下使用协议时,您要使用的协议类需要符合协议。

协议可能需要通过符合类型来实现特定的实例方法和类型方法。这些方法作为协议定义的一部分编写,与普通实例和类型方法完全相同,但没有花括号或方法体。允许使用变量参数,遵循与常规方法相同的规则。但是,无法为协议定义中的方法参数指定默认值。

可选函数不需要构造委托,就像在一些必需的方法和一些可选函数中的表视图一样。您可以根据您的要求使用。

一级

import UIKit

//Here you creating protocol
@objc protocol MangoDelegate {
    func eatmango()
    optional func donoteat()
}

class ProtocolController: UIViewController {

    var delegate: MangoDelegate?


    override func viewDidLoad() {
        super.viewDidLoad()

    }

}

第二类使用协议

import UIKit

class ViewController: UIViewController , MangoDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    //MARK: - delegate method
    func eatmango(){

    }

}

在这段代码中,我只使用了所需的功能和不符合协议的选项。

没有方法构造协议

enter image description here

@try在这里符合协议与可选功能,但又需要构造

enter image description here

尝试使用必需功能

enter image description here

并尝试使用这两个功能

enter image description here

答案 2 :(得分:0)

什么是可选功能?

可选函数是在协议中声明的函数,不必由符合此类协议的类实现。

为什么不必声明方法?

嗯,因为它是可选的。

它的用途是什么?

一个例子可能是回答这个问题的最好方法。

您有一个协议Bird(从技术上讲,这个协议应该是一个类,但这是我头脑中的第一个例子。)

在此协议中,您有必需的eat()和可选的fly()

您有2个类实现协议BirdDodoEagle(同样,从技术上讲,它们应该是Bird类的子类,但这只是一个简单的例子。)

DodoEagle都必须实施eat(),因为(希望)都会吃掉。

然而,当谈到飞行时,老鹰会做(假设两个机翼都有功能),但是dodos没有。因此,您应该为fly()实施Eagle,而不应为Dodo实施。{/ p>

答案 3 :(得分:0)

如果你想避免@objc但仍然有可选功能的好处,只需使用协议功能的空(或默认)实现扩展协议,例如 -

protocol MyProtocol: class {
    func myFunc()
}

extension MyProtocol {
    func myFunc() {
        // do nothing (or something...)
    }
}

这意味着您不必在班级中实施该功能