3月29號,蘋果正式發布了iOS10.3,作為iOS開發者,自然也很關注每次伴隨iOS更新而發布的XCode,
這次蘋果發布的是XCode8.3,同時Swift3.1也一起發布。Swift3.1的新特性網上已經有很多相關文章說明了。
但是有一點都沒有提到:就是initialize方法被標記在未來的Swift版本將不能再使用。
下面我來告訴大家在Swift3.1時面用什么來替換initialize方法。
雖然現在的Swift3.1版本還可以用,但是已經被警告了,
發布到Cocopods將不被接受。所以還是要想辦法移除這個警告。
我百度這個問題,發現基本沒有答案,所以只好在萬能的Stackoverflow中尋找。
果然,第一問題在高票答案完美地解決了這個問題。
下面我盡量翻譯過來讓大家看明白
容易簡單的解決方案
大部分App的入口點是AppDelegate
的
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
your code
}
方法。當App啟動完后會調用該方法。所以你只要在你自己的類定義一個靜態初始化方去,然后再在里面調用該靜態方法就可以了。
比如經典的IQKeyboardManager
就是這樣啟動的。
有講究深度的解決方案
上面那個方法可能有點不省心,如果你想創建一個框架伴隨APP啟動而啟動,但是又也不想在AppDelegate的方法里來初始化。
而是在APP啟動時就讓它默默調用。那么可通知以下方案
第一步:定義協議
定義下面的swift代碼,包含一個protocal
和 class
。目的是為所有類提供一個簡單的入口點來達到類似initialize
的效果。你可以自定義一個類
來實現SelfAware協議。SelfAware協
議內有一個awake
方法,該方法是初始化代碼的核心方法。
public protocol SelfAware:class { // 定義SelfAware協議
static func awake()
}
class NothingToSeeHere{
static func harmlessFunction(){
let typeCount = Int(objc_getClassList(nil, 0))
let types = UnsafeMutablePointer<AnyClass?>.allocate(capacity: typeCount)
let autoreleaseintTypes = AutoreleasingUnsafeMutablePointer<AnyClass?>(types)
objc_getClassList(autoreleaseintTypes, Int32(typeCount)) //獲取所有的類
for index in 0 ..< typeCount{
(types[index] as? SelfAware.Type)?.awake() //如果該類實現了SelfAware協議,那么調用awake方法
}
types.deallocate(capacity: typeCount)
}
}
上面的代碼對于大部分的iOS開發者可能看不習慣,因為我們平時開發很少使用到指針。但是看懂并不難。簡單來說就是找出該項目所有的class
,如果該class
實現了SelfAware
協議,那么調用awake
方法。這樣你就可以自定義你自己的類來實現SelfAware
協議達到這個效果
第二步:讓APP啟動時只執行一次harmlessFunction
方法
有了上面的代碼,現在還有一種重要的事情,就是讓APP啟動的時侯運行NothingToSeeHere.harmlessFunction
方法。先前,這個一般最好使用Objc來
實現這個功能,但是在這在里只能使用Swift,參考以下代碼
extension UIApplication{
private static let runOnce:Void = { //使用靜態屬性以保證只調用一次(該屬性是個方法)
NothingToSeeHere.harmlessFunction()
}()
open override var next: UIResponder?{ //重寫next屬性
UIApplication.runOnce
return super.next
}
}
在這里擴展了UIApplication
并重寫了next
屬性,關于UIApplication
的next
屬性有興趣的開發者可以去看iOS事件傳遞機制文章。這里就不說了
在iOS的事件響應過程中next
會調用多次。但是這里使用靜態的runOnce
屬性來保證只會調用一次。然后再在該屬性里調用NothingToSeeHere
的harmlessFunction
方法
第三步:?自定義類實現SelfAware
協議,重寫awake
方法
接下來的事情就很簡單了,現在我們在App啟動的時侯有了入口點,還有在啟動過程中勾住啟動點的類,剩下你只要自定義一個類實現SelfAware
即可
class ProjectStart: SelfAware {
static func awake() {
your code
}
}
上面有些是翻譯stackoverflow
原回答,自己也加了些東西。?相信讀者應該不能理解。雖然在大部分開發者在項目里使用iOS runtime的東西并不多,
但是有時侯這些黑魔法還是非常好用的。 另外從這個警告也可以看出,蘋果在將來會慢慢在swift中移除Objc的一些方法。所以使用swift實現iOS runtime
要謹慎。