返回
Swift系列三十 - 从OC到Swift(二)
IOS
2024-01-31 18:29:25
一、协议
1.1. 只能被class继承的协议
示例代码:
@objc protocol MyProtocol {
func myMethod()
}
class MyClass: NSObject, MyProtocol {
func myMethod() {
print("Hello, world!")
}
}
let myObject = MyClass()
myObject.myMethod() // 输出:Hello, world!
被@objc修饰的协议,还可以暴露给OC去遵守实现。
1.2. 可选协议
正常情况下,Swift中的协议是必须遵守的,否则会报错。但是,我们可以使用@optional来声明一个可选协议,这样,在遵守该协议时就可以选择性地实现协议中的方法。
示例代码:
@objc optional protocol MyOptionalProtocol {
func myOptionalMethod()
}
class MyClass: NSObject, MyOptionalProtocol {
func myOptionalMethod() {
print("Hello, world!")
}
}
let myObject = MyClass()
myObject.myOptionalMethod?() // 输出:Hello, world!
二、关联对象
关联对象是Objective-C中的一种机制,允许向对象添加额外的属性,而不会修改对象的接口。关联对象可以用于存储私有数据、实现委托模式等。
在Swift中,关联对象可以通过objc_setAssociatedObject()
和objc_getAssociatedObject()
函数来使用。
示例代码:
class MyClass {
var associatedObject: Any?
func setAssociatedObject(object: Any?) {
objc_setAssociatedObject(self, &kMyAssociatedObjectKey, object, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
func getAssociatedObject() -> Any? {
return objc_getAssociatedObject(self, &kMyAssociatedObjectKey)
}
}
let myObject = MyClass()
myObject.setAssociatedObject(object: "Hello, world!")
let associatedObject = myObject.getAssociatedObject() as? String
print(associatedObject) // 输出:Hello, world!
三、KVO
KVO(Key-Value Observing)是一种机制,允许对象观察其他对象的属性的变化。当被观察对象的属性发生变化时,观察对象将收到通知。
在Swift中,KVO可以通过addObserver(_:forKeyPath:options:context:)
方法来实现。
示例代码:
class MyClass {
@objc dynamic var myProperty: Int = 0
}
class ObserverClass {
var myObject: MyClass
init(myObject: MyClass) {
self.myObject = myObject
myObject.addObserver(self, forKeyPath: "myProperty", options: [.new, .old], context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "myProperty" {
let oldValue = change?[.oldKey] as? Int
let newValue = change?[.newKey] as? Int
print("Old value: \(oldValue), new value: \(newValue)")
}
}
}
let myObject = MyClass()
let observer = ObserverClass(myObject: myObject)
myObject.myProperty = 10
输出:
Old value: nil, new value: 10