Swift环境中Load与Initialize的实现
背景
最近在开始一个新的项目预研,预研的主要工作一般就是语言选型,需要用到什么开源库、还有就是项目架构的初步搭建,项目中需要用到技术的攻关诸如此类的。
在语言选型暂时选定为swift,因为swift相对于Objective-C的优势,就暂且不表了,对于我的吸引,更多的是更加简洁的语法,更加少的代码量这两项就足以让我这个新手去尝试的踩一下坑了。
在考虑使用swift的时候,就必须解决swift在Objective-C语言上不支持的一些特性,尽量去抹平这两个语言技术上的开发差距。虽然因为对swift语言不熟悉,但是还是需要尽量避免在正式进入业务开发的时候因为碰到一下语言问题而卡壳,还是一个必须提前解决的问题。
在开源库上,目前iOS开发上大多数的开源库,大多数都能兼容swift的开发或者能找好很的用swift实现的替代品。所以更多还是考虑预研平台上的差距,比如runtime一些动态特性是否还能继续使用。通过一轮的google,发现swift在使用runtime上面还是没有太大问题的。在考虑埋点的时候,需要用到method swizzle,而method swizzle一般是在类加载的时候进行操作,而swift环境中使用load方法时提示:Method 'load()' defines Objective-C class method 'load', which is not permitted by Swift
,也就是load方法已经不在许可在swift中使用。
这就是在这篇文章的背景。
现状
目前网上的blog大多数的解决方案,都是来自一篇博客Handling the Deprecation of initialize(),通过UIApplication来进行初始化来实现,具体就不在分析了。
这个方案已经很大程度上解决了这个问题,作为一个简洁派的代码狗来说,这个方式略显繁琐,而且也不优雅。于是乎,就有了这个个人认为比较优雅的方式。
实现方式
这个方式有以下几个特点:
完全特性Objective-C中load和initialize类方法一摸一样
无论在纯swift环境或者是swift与OC混编环境都能很好的运行
代码非常简单
其实是一个非常简单的方式,但是却是一个功能和oc环境一样的load和initialize方法,原理也很简单。这个类库暂且叫SwiftyLoad。
传送门:SwiftyLoad
定义一个协议
定义一个教NSSwiftyLoadProtocol的协议,该协议的目的是在swift环境中接受load和initialize的回调。
swift环境中需要使用load或者initialize方法的类,在extension中实现NSSwiftyLoadProtocol。
需要添加load方法和initialize方法的类添加分类
使用宏为每一个需要添加load方法或者initialize方法的类,添加一个category分类,该分类是调用swift环境中extension扩展中实现了协议的swiftyLoad和swiftyInitialize方法的实际实现。
使用
使用SwiftyLoad有两种情况
纯swift环境
需要使用SwiftyLoad库的类需要用
@objc
关键字修饰在纯swift环境中,在工程中添加任意的swift.m(不叫swift也可以,名字任意)代码
在swift.m文件中使用
SWIFTY_LOAD_INITIALIZE(TestClass)
来创建分类需要TestClass便携式extension并实现NSSwiftyLoadProtocol协议即可
Swift与OC混编环境
- 步骤与以上大同小异
最后
在github的代码中,有详细的使用例子