我看到很多以下格式的例子:
extension Protocolname where Self: UIViewController
where Self
在协议扩展中是什么?我找不到相关文档。
我看到很多以下格式的例子:
extension Protocolname where Self: UIViewController
where Self
在协议扩展中是什么?我找不到相关文档。
protocol Meh {
func doSomething()
}
// Extend protocol Meh, where `Self` is of type `UIViewController`
// func blah() will only exist for classes that inherit `UIViewController`.
// In fact, this entire extension only exists for `UIViewController` subclasses.
extension Meh where Self: UIViewController {
func blah() {
print("Blah")
}
func foo() {
print("Foo")
}
}
class Foo : UIViewController, Meh { //This compiles and since Foo is a `UIViewController` subclass, it has access to all of `Meh` extension functions and `Meh` itself. IE: `doSomething, blah, foo`.
func doSomething() {
print("Do Something")
}
}
class Obj : NSObject, Meh { //While this compiles, it won't have access to any of `Meh` extension functions. It only has access to `Meh.doSomething()`.
func doSomething() {
print("Do Something")
}
}
let i = Obj()
i.blah()
let j = Foo()
j.blah()
Meh.blah()
只对 UIViewController
类型的类可用。下面是一个示例,解释了where self: UIViewController的用途:
protocol SBIdentifiable {
static var sbIdentifier: String { get }
}
extension SBIdentifiable where Self: UIViewController {
static var sbIdentifier: String {
return String(describing: self)
}
}
extension UIVieWcontroller: SBIdentifiable { }
class ViewController: UIViewController {
func loadView() {
/*Below line we are using the sbIdentifier which will return the
ViewController class name.
and same name we would mentioned inside ViewController
storyboard ID. So that we do not need to write the identifier everytime.
So here where Self: UIViewController means it will only conform the protocol of type UIViewController*/
let viewController = self.instantiateViewController(withIdentifier:
self.sbIdentifier) as? SomeBiewController
}
}
您可以在这里找到相同的示例: WWDC2015-408,(强烈建议观看它,因为它说明了原因)
此外,另一个类似的示例是使用泛型where子句的扩展
struct Stack<Element> {
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
}
where子句会对扩展进行限制,因此只有当堆栈中的项目可比较时,扩展才会添加isTop(_:)方法。
extension Stack where Element: Equatable {
func isTop(_ item: Element) -> Bool {
guard let topItem = items.last else {
return false
}
return topItem == item
}
}
protocol Meh
和extension Meh where Self: UIViewController
中使用相同的名称Meh
,这对我来说似乎很令人困惑。 - FelixUIViewController
实现它时。 - Brandon