您好,登錄后才能下訂單哦!
//MARK: - 主題更改時,自動執行
extension NSObject {
fileprivate struct AssociatedKeys {
static var thmemChanged = "thmemChanged"
}
/// 當前主題更改時、第一次設置時 自動調用的閉包
public typealias ThemeChangedClosure = @convention(block) (_ style:String) -> Void
/// 自動調用的閉包
/// 設置時,會設置一個KVO監聽,當V2Style.style更改時、第一次賦值時 會自動調用這個閉包
var thmemChangedHandler:ThemeChangedClosure? {
get {
let closureObject: AnyObject? = objc_getAssociatedObject(self, &AssociatedKeys.thmemChanged) as AnyObject?
guard closureObject != nil else{
return nil
}
let closure = unsafeBitCast(closureObject, to: ThemeChangedClosure.self)
return closure
}
set{
guard let value = newValue else{
return
}
let dealObject: AnyObject = unsafeBitCast(value, to: AnyObject.self)
objc_setAssociatedObject(self, &AssociatedKeys.thmemChanged,dealObject,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
//設置KVO監聽
self.kvoController.observe(V2EXColor.sharedInstance, keyPath: "style", options: [.initial,.new] , block: {[weak self] (nav, color, change) -> Void in
self?.thmemChangedHandler?(V2EXColor.sharedInstance.style)
}
)
}
}
}
class V2EXColor :NSObject {
fileprivate static let STYLE_KEY = "styleKey"
static let V2EXColorStyleDefault = "Default"
static let V2EXColorStyleDark = "Dark"
fileprivate static var _colors:V2EXColorProtocol?
static var colors :V2EXColorProtocol {
get{
if let c = V2EXColor._colors {
return c
}
else{
if V2EXColor.sharedInstance.style == V2EXColor.V2EXColorStyleDefault{
return V2EXDefaultColor.sharedInstance
}
else{
return V2EXDarkColor.sharedInstance
}
}
}
set{
V2EXColor._colors = newValue
}
}
dynamic var style:String
static let sharedInstance = V2EXColor()
fileprivate override init(){
if let style = V2EXSettings.sharedInstance[V2EXColor.STYLE_KEY] {
self.style = style
}
else{
self.style = V2EXColor.V2EXColorStyleDefault
}
super.init()
}
func setStyleAndSave(_ style:String){
if self.style == style {
return
}
if style == V2EXColor.V2EXColorStyleDefault {
V2EXColor.colors = V2EXDefaultColor.sharedInstance
}
else{
V2EXColor.colors = V2EXDarkColor.sharedInstance
}
self.style = style
V2EXSettings.sharedInstance[V2EXColor.STYLE_KEY] = style
}
}
如果您有過OC的開發經驗,那一定會對OC中@dynamic關鍵字比較熟悉,它告訴編譯器不要為屬性合成getter和setter方法。
Swift中也有dynamic關鍵字,它可以用于修飾變量或函數,它的意思也與OC完全不同。它告訴編譯器使用動態分發而不是靜態分發。OC區別于其他語言的一個特點在于它的動態性,任何方法調用實際上都是消息分發,而Swift則盡可能做到靜態分發。
因此,標記為dynamic的變量/函數會隱式的加上@objc關鍵字,它會使用OC的runtime機制。
雖然靜態分發在效率上可能更好,不過一些app分析統計的庫需要依賴動態分發的特性,動態的添加一些統計代碼,這一點在Swift的靜態分發機制下很難完成。這種情況下,雖然使用dynamic關鍵字會犧牲因為使用靜態分發而獲得的一些性能優化,但也依然是值得的。
class Kraken { dynamic var imADynamicallyDispatchedString: String dynamic func imADynamicallyDispatchedFunction() { //Hooray for dynamic dispatch! } }
使用動態分發,您可以更好的與OC中runtime的一些特性(如CoreData,KVC/KVO)進行交互,不過如果您不能確定變量或函數會被動態的修改、添加或使用了Method-Swizzle,那么就不應該使用dynamic關鍵字,否則有可能程序崩潰。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。