在Swift3.1中 initialize被警告未來會禁用(disallow),那么來什么來代替它呢

3月29號,蘋果正式發布了iOS10.3,作為iOS開發者,自然也很關注每次伴隨iOS更新而發布的XCode,
這次蘋果發布的是XCode8.3,同時Swift3.1也一起發布。Swift3.1的新特性網上已經有很多相關文章說明了。
但是有一點都沒有提到:就是initialize方法被標記在未來的Swift版本將不能再使用。
下面我來告訴大家在Swift3.1時面用什么來替換initialize方法。

在未來的Swift版本中initialize將不可用

雖然現在的Swift3.1版本還可以用,但是已經被警告了,
發布到Cocopods將不被接受。所以還是要想辦法移除這個警告。
我百度這個問題,發現基本沒有答案,所以只好在萬能的Stackoverflow中尋找。
果然,第一問題在高票答案完美地解決了這個問題。

http://stackoverflow.com/questions/42824541/swift-3-1-deprecates-initialize-how-can-i-achieve-the-same-thing

下面我盡量翻譯過來讓大家看明白

容易簡單的解決方案

大部分App的入口點是AppDelegate

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
    your code
}

方法。當App啟動完后會調用該方法。所以你只要在你自己的類定義一個靜態初始化方去,然后再在里面調用該靜態方法就可以了。
比如經典的IQKeyboardManager就是這樣啟動的。

有講究深度的解決方案

上面那個方法可能有點不省心,如果你想創建一個框架伴隨APP啟動而啟動,但是又也不想在AppDelegate的方法里來初始化。
而是在APP啟動時就讓它默默調用。那么可通知以下方案

第一步:定義協議

定義下面的swift代碼,包含一個protocalclass。目的是為所有類提供一個簡單的入口點來達到類似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屬性,關于UIApplicationnext屬性有興趣的開發者可以去看iOS事件傳遞機制文章。這里就不說了
在iOS的事件響應過程中next會調用多次。但是這里使用靜態的runOnce屬性來保證只會調用一次。然后再在該屬性里調用NothingToSeeHereharmlessFunction方法

第三步:?自定義類實現SelfAware協議,重寫awake方法

接下來的事情就很簡單了,現在我們在App啟動的時侯有了入口點,還有在啟動過程中勾住啟動點的類,剩下你只要自定義一個類實現SelfAware即可

class ProjectStart: SelfAware {
    static func awake() {
         your code
    }
}

上面有些是翻譯stackoverflow原回答,自己也加了些東西。?相信讀者應該不能理解。雖然在大部分開發者在項目里使用iOS runtime的東西并不多,
但是有時侯這些黑魔法還是非常好用的。 另外從這個警告也可以看出,蘋果在將來會慢慢在swift中移除Objc的一些方法。所以使用swift實現iOS runtime
要謹慎。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容