【问题标题】:Optional Variables in protocol is possible?协议中的可选变量是可能的吗?
【发布时间】:2017-06-01 12:12:49
【问题描述】:
protocol AProtocol: BProtocol {
    /// content to be shown on disclaimer Label of cell
    var disclaimer: String {get set}
    var cellDisclaimerAttributed: NSAttributedString {get}
    var showSelection: Bool {get set}
    var isReadMore: Bool {get}
}

我想让变量成为可选的,这样我就不需要在每次符合协议后都实现所有变量。就像在 Objective-C 中我们对方法所做的那样:

protocol AProtocol: BProtocol {
    /// content to be shown on disclaimer Label of cell
    optional var disclaimer: String {get set}
    optional var cellDisclaimerAttributed: NSAttributedString {get}
    optional var showSelection: Bool {get set}
    optional var isReadMore: Bool {get}
}

有可能吗?

【问题讨论】:

  • 您给出的第二个示例的错误消息是 "'optional' 只能应用于 @objc 协议的成员"(提示提示)
  • 以上链接仅讨论方法。 @MartinR
  • @Ren:你确定吗?我刚试过@objc protocol MyProtocol { @objc optional var disclaimer: String { get set } }class Foo: MyProtocol { }
  • @Ren:如果 AProtocol 从 BProtocol 继承,那么当然 both 协议(和可选属性)必须用 @objc 标记。

标签: swift protocols


【解决方案1】:
protocol TestProtocol {
    var name : String {set get}
    var age : Int {set get}
}

为协议提供默认扩展。为所有变量集提供默认实现,并获取您希望它们是可选的。

在下面的协议中,姓名和年龄是可选的。

 extension TestProtocol {

    var name: String {
        get { return "Any default Name" } set {}
    }  
    var age : Int { get{ return 23 } set{} }      
}

现在,如果我将上述协议符合任何其他类,例如

class TestViewController: UIViewController, TestProtocol{
        var itemName: String = ""

**I can implement the name only, and my objective is achieved here, that the controller will not give a warning that "TestViewController does not conform to protocol TestProtocol"**

   var name: String {
        get {
            return itemName ?? ""
        } set {}
    }
}

【讨论】:

  • 请注意,在TestViewController 中您不需要实现get set。只需将变量定义为 var itemName: String = "" 即可。
  • 小心!在此解决方案中,nameage 不能从实例更改,例如:设置 testVC.age = 30 后,age 仍为 23!
【解决方案2】:

如果你想conform to Swift's documentation,你必须像这样实现它:

@objc protocol Named {
    // variables
    var name: String { get }
    @objc optional var age: Int { get }
  
    // methods
    func addTen(to number: Int) -> Int
    @objc optional func addTwenty(to number: Int) -> Int
}

class Person: Named {
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    func addTen(to number: Int) -> Int {
        return number + 10
    }
}

【讨论】:

    猜你喜欢
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 2016-10-14
    • 1970-01-01
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    相关资源
    最近更新 更多