swiftui和oc差别 swift协议和oc协议的区别
转载
- swift 基本类都是继承于协议
- swift 可以通过协议的默认实现,进行无痕扩展
Swift 的协议和 Objective-C 的协议不同。Swift 协议可以被用作代理,也可以让你对接口进行
抽象 (比如 IteratorProtocol 和 Sequence)。它们和 Objective-C 协议的最大不同在于我们可以
让结构体和枚举类型满足协议。除此之外,Swift 协议还可以有关联类型。我们还可以通过协议
扩展的方式为协议添加方法实现。我们会在面向协议编程的部分讨论所有这些内容。
协议允许我们进行动态派发,也就是说,在运行时程序会根据消息接收者的类型去选择正确的
方法实现。不过,方法到底什么时候是动态派发,什么时候不是动态派发,有时却不是那么直
观,并有可能造成令人意外的结果。我们会在下一节中看到这个问题。
普通的协议可以被当作类型约束使用,也可以当作独立的类型使用。带有关联类型或者 Self 约
束的协议特殊一些:我们不能将它当作独立的类型来使用,所以像是 let x: Equatable 这样的
写法是不被允许的;它们只能用作类型约束,比如 func f<T: Equatable>(x: T)。这听起来似乎
是一个小限制,但是这在实践中让带有关联类型的协议成为了完全不同的东西。我们会在之后
详细对此说明,我们还将讨论如何使用 (像是 AnyIterator 这样的) 类型消除的方法来让带有关
联类型的协议更加易用。
在面向对象编程中,子类是在多个类之间共享代码的有效方式。一个子类将从它的父类继承所
有的方法,然后选择重写其中的某些方法。比如,我们可以有一个 AbstractSequence 类,以
及像是 Array 和 Dictionary 这样的子类。这么做的话,我们就可以在 AbstractSequence 中添
加方法,所有的子类都将自动继承到这些方法。
不过在 Swift 中,Sequence 中的代码共享是通过协议和协议扩展来实现的。通过这么做,
Sequence 协议和它的扩展在结构体和枚举这样的值类型中依然可用,而这些值类型是不支持
子类继承的。
不再依赖于子类让类型系统更加灵活。在 Swift (以及其他大多数面向对象的语言) 中,一个类
只能有一个父类。当我们创建一个类时,我们必须同时选择父类,而且我们只能选择一个父类,
我们无法创建比如同时继承了 AbstractSequence 和 Stream 的类。这有时候会成为问题。在
Cocoa 中就有一些例子,比如 NSMutableAttributedString,框架的设计师必须在
NSAttributedString 和 NSMutableString 之间选择一个父类。
Demo 给UIView 无痕扩展一个方法
// 给 UIView 扩展一个方法 test()
// 扩展方式优美有和谐
struct TestFunction<TE> {
let base: TE
init(_ te: TE) {
base = te
}
}
protocol TestFunctionProtocol {
associatedtype Compatible
var tb: TestFunction<Compatible> { get }
static var tb : TestFunction<Compatible>.Type { get }
}
extension TestFunctionProtocol {
var tb: TestFunction<Self> {
return TestFunction(self)
}
static var tb : TestFunction<Self>.Type {
return TestFunction<Self>.self
}
}
// 下面注释代码保证 TestFunction 不会重复创建
//var tbbb = "tb"
//extension TestFunctionProtocol {
// var tb: TestFunction<Self> {
// var cache = objc_getAssociatedObject(self, &tbbb)
// if let cache = cache {
// return cache as! TestFunction<Self>
// }
// cache = TestFunction(self)
// objc_setAssociatedObject(self, &tbbb, cache, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
// return cache as! TestFunction<Self>
// }
// static var tb : TestFunction<Self>.Type {
// return TestFunction<Self>.self
// }
//}
extension TestFunction where TE: UIView {
func test() {
print("this is my test")
}
}
extension UIView: TestFunctionProtocol {}
let v = UIView()
v.tb.test()
本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。