Swift 协议:隐藏一些属性

And*_*nko 5 swift swift-protocols

我想trimmedTextUITextViewand创建一个属性UITextField。这是我所做的:

protocol TrimmedTextSupporting: class {
  var _text: String? { get }
  var trimmedText: String { get }
}

extension TrimmedTextSupporting {
  var trimmedText: String {
    let text = self._text ?? ""
    return text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
  }
}

extension UITextField: TrimmedTextSupporting {

  var _text: String? {
    return self.text
  }
}

extension UITextView: TrimmedTextSupporting {

  var _text: String? {
    return self.text
  }
}
Run Code Online (Sandbox Code Playgroud)

我需要_text财产,因为text被声明为String?inUITextField和 as String!inUITextView (whyyyy?!>_<)。现在我想隐藏这个属性以避免混淆 API。

这是我尝试过的:

1) 将其标记为private. 编译器不允许这样做:'private' modifier cannot be used in protocols

2)分离成私有协议:

private protocol TextExposing {
  var _text: String? { get }
}

extension UITextField: TextExposing {
  var _text: String? {
    return self.text
  }
}

extension UITextView: TextExposing {
  var _text: String? {
    return self.text
  }
}

///////

protocol TrimmedTextSupporting: class {
  var trimmedText: String { get }
}

extension UITextField: TrimmedTextSupporting {}

extension UITextView: TrimmedTextSupporting {}

extension TrimmedTextSupporting where Self: TextExposing {

  // compiler error
  var trimmedText: String {
    let text = self._text ?? ""
    return text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
  }
}
Run Code Online (Sandbox Code Playgroud)

但是编译器再次抱怨: Property 'trimmedText' must be declared internal because it matches a requirement in internal protocol 'TrimmedTextSupporting'

我没有想法。

Mik*_*ard 4

我倾向于选择:

protocol TrimmedTextSupporting: class {
    var trimmedText: String { get }
}

extension TrimmedTextSupporting {

    private func trimText(text: String) -> String {
        return text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    }
}

extension UITextField: TrimmedTextSupporting {

    var trimmedText: String {
        return trimText(text ?? "")
    }
}

extension UITextView: TrimmedTextSupporting {

    var trimmedText: String {
        return trimText(text ?? "")
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,您可以通过在共享和私有函数中执行此操作来避免重复艰苦的工作,并且扩展UITextFieldUITextView只执行所需的最少操作。