流著淚,做Swift3.0遷移適配

Swift3.0最大的變化妨马,有太多太多挺举,沒(méi)有最大,只有一樣大烘跺。
  先前工程除了第三方庫(kù)湘纵,其余全部用Swift開(kāi)發(fā),也經(jīng)歷了2.1到2.2的遷移滤淳,2.2到2.3的遷移梧喷。在2.3版本時(shí),編譯器已經(jīng)有了一些警告脖咐,某些語(yǔ)法將在Swift3.0中不能再使用伤柄,比如參數(shù)中的var聲明,UIButton的構(gòu)造方法等等文搂。但讓人沒(méi)想到的是适刀,Swift3.0真正到來(lái)時(shí),更需要花費(fèi)我2天的時(shí)間埋頭改改改煤蹭。謹(jǐn)以此文笔喉,記錄遷移過(guò)程取视。

注意事項(xiàng)

手里兩個(gè)業(yè)務(wù)工程用Swift遷移工具,其中有一個(gè)因?yàn)镃ocoaPods的原因常挚,一直卡在Generating Preview的階段作谭。后來(lái)偶然因?yàn)镃ocoaPods由于GFW的原因不能執(zhí)行update命令更新第三方庫(kù),我把CocoaPods去掉了奄毡,第三方庫(kù)直接放主工程里折欠,恢復(fù)原始工程結(jié)構(gòu),就可以正常遷移了吼过。

自動(dòng)遷移部分

  1. 已經(jīng)聲明的枚舉值被全部改為首字母小寫(xiě)锐秦,因?yàn)樾乱?guī)范認(rèn)為枚舉相當(dāng)于類(lèi),值是成員盗忱,那么成員就應(yīng)當(dāng)以駝峰法命名酱床,首字母小寫(xiě);
  2. 已經(jīng)聲明的方法被拆分調(diào)用趟佃。比如autolayout的封裝庫(kù)PureLayout扇谣,設(shè)置布局的方法autoPinEdgeToSuperviewEdge()變成autoPinEdge(toSuperviewEdge:);諸如此類(lèi)還有很多闲昭,例如UIColor.whiteColor() -> UIColor.white......總之罐寨,盡可能的讓能推斷出類(lèi)型的情況,少寫(xiě)重復(fù)詞序矩。當(dāng)然鸯绿,還有變長(zhǎng)的方法名,例如view.hidden -> view.isHidden贮泞。
  3. 關(guān)于類(lèi)成員變量的權(quán)限楞慈,遷移工具默認(rèn)將先前的private權(quán)限改為fileprivate,因?yàn)樾乱?guī)范中的private就算在同文件中但不在同一個(gè)類(lèi)里也是無(wú)訪問(wèn)權(quán)限的啃擦。因此先前的private權(quán)限囊蓝,等同于現(xiàn)在的fileprivate。
  4. closure閉包現(xiàn)在有了更詳細(xì)的宏聲明了令蛉,聲明閉包是否會(huì)作為存儲(chǔ)型變量被強(qiáng)引用聚霜。因?yàn)閷?duì)閉包的強(qiáng)引用會(huì)導(dǎo)致外部對(duì)象一直不能被釋放,外部就需要使用weak var 來(lái)讓closure對(duì)傳入的對(duì)象只保持弱引用珠叔。不顯式聲明默認(rèn)是非存儲(chǔ)型閉包蝎宇,當(dāng)閉包被強(qiáng)引用則需要添加@escaping,位置在變量冒號(hào)后面祷安,類(lèi)型前面姥芥,例如
    failureCallback: @escaping ((_ errorMsg: String) -> Void)
  5. 方法聲明參數(shù)現(xiàn)在分三部分,冒號(hào)左邊一部分是標(biāo)簽汇鞭,另一部分是參數(shù)名凉唐,冒號(hào)右邊是變量類(lèi)型庸追。在Swift3.0以前,標(biāo)簽可有可無(wú)台囱,沒(méi)有標(biāo)簽時(shí)直接用變量名當(dāng)標(biāo)簽使用淡溯;Swift3.0規(guī)范了方法命名,規(guī)定必須使用標(biāo)簽簿训,如果強(qiáng)制不使用標(biāo)簽咱娶,那么方法聲明時(shí)標(biāo)簽用一根下劃線"_"替代。自動(dòng)遷移工具無(wú)法完成更詳細(xì)的識(shí)別强品,因此只能把大部分方法的標(biāo)簽先改為"_"膘侮。

手動(dòng)遷移部分

  1. 按照新規(guī)范,其實(shí)所有的方法命名都應(yīng)該重寫(xiě)择懂。自動(dòng)遷移讓大部分方法的參數(shù)標(biāo)簽喻喳,都變?yōu)榱?"另玖。這只是一個(gè)過(guò)渡的困曙,能讓程序快速通過(guò)編譯的方案,如果有足夠時(shí)間谦去,方法名最好規(guī)范起來(lái)慷丽。
    例如
    func reloadUIWithData(
    data: BaseData?) {}
    新規(guī)范下,命名為:
    func reloadUI(withData data: BaseData?) {}

  2. 閉包作為參數(shù)聲明時(shí)鳄哭,標(biāo)簽只能用"_"要糊。調(diào)用閉包則不需要標(biāo)簽,直接寫(xiě)值妆丘,多個(gè)參數(shù)值用","分隔锄俄。
    例如
    func request(_ redPacketID: Int64,
    successCallback: @escaping ((_ code: Int32, _ msg: String, _ rsp: RspLookRedPackage) -> Void),
    failureCallback: @escaping ((_ errorMsg: String) -> Void)) {
    }
    調(diào)用時(shí),寫(xiě):
    successCallback(rspMessage.rsp.retCode, rspMessage.rsp.retMsg, rspResult)

  3. Swift語(yǔ)言本身不支持同名方法重載勺拣,碰到需要重載的場(chǎng)景一般都是用不同數(shù)量參數(shù)奶赠,或不同的起始方法名來(lái)解決。如果第三方庫(kù)中的方法名药有,被Swift3.0拆分成了相同起始方法名相同參數(shù)數(shù)量的方法毅戈,則需要Objective-C文件做橋接。
    SDWebImage庫(kù)中愤惰,為UIImage下載圖片有以下兩個(gè)方法:
    - (void)sd_setImageWithURL:(NSURL *)url
    placeholderImage:(UIImage *)placeholder
    options:(SDWebImageOptions)options {}

     - (void)sd_setImageWithURL:(NSURL *)url 
               placeholderImage:(UIImage *)placeholder 
                      completed:(SDWebImageCompletionBlock)completedBlock { }
    

在Swift3.0中苇经,會(huì)被識(shí)別成


Swift3.0拆分了部分方法起始名字

那么,在使用sd_setImage(with:....)時(shí)宦言,編譯器會(huì)報(bào)如下錯(cuò):


方法具有二義性

解決方法就是創(chuàng)建一個(gè)Objective-C類(lèi)別扇单,添加起始方法名不同的方法名。
//頭文件

#import <UIKit/UIKit.h>
#import <UIImageView+WebCache.h>

    @interface UIImageView (SDWebImageSwiftBridge)

    - (void)swiftBridge_sd_setImageWithURL:(NSURL *)url
                          placeholderImage:(UIImage *)placeholder
                                 completed:(SDWebImageCompletionBlock)completedBlock;

    @end
    //實(shí)現(xiàn)文件
    @implementation UIImageView (SDWebImageSwiftBridge)

    - (void)swiftBridge_sd_setImageWithURL:(NSURL *)url
                          placeholderImage:(UIImage *)placeholder
                                 completed:(SDWebImageCompletionBlock)completedBlock {
        [self sd_setImageWithURL:url placeholderImage:placeholder completed:completedBlock];
    }

    @end
  1. 以上全部完成后奠旺,編譯運(yùn)行蜘澜,立即就發(fā)現(xiàn)了一個(gè)bug阻桅。比如聲明的String!類(lèi)型值,在用=賦值后兼都,類(lèi)型就變成了String?嫂沉。在Swift3.0以前,String!類(lèi)型的值傳遞或經(jīng)方法返回后扮碧,可以直接當(dāng)String類(lèi)型的用趟章。也就是說(shuō),如果現(xiàn)在String!需要傳遞或作為方法返回值慎王,要么強(qiáng)制解包成String再傳蚓土,要么不解包傳到別處就是String?。String?對(duì)象在被使用時(shí)赖淤,假如值是"123"蜀漆,那么它將會(huì)是Optional("123")樣式。比如拼接網(wǎng)址時(shí)咱旱,這樣網(wǎng)址的網(wǎng)頁(yè)就無(wú)法打開(kāi)确丢。
    寫(xiě)了更多的Swift3.0代碼,發(fā)現(xiàn)了設(shè)計(jì)的根本所在吐限。在Swift3.0中鲜侥,所有聲明為Optional的類(lèi)型,直接打印的話都會(huì)被當(dāng)做非強(qiáng)制解包類(lèi)型诸典。比如下面代碼

Swift3.0中無(wú)論類(lèi)型后是?還是!描函,直接打印都算有Optional()包裹

因此,以往String!類(lèi)型對(duì)象打印值等同于String的情況狐粱,已經(jīng)變成了String!打印值等同于String?舀寓,為Optional("")
我想,這樣的變動(dòng)肌蜻,更多是出于嚴(yán)格區(qū)分普通類(lèi)型和可選類(lèi)型互墓,進(jìn)一步加強(qiáng)安全性的舉措。之前的版本里宋欺,如果一個(gè)方法的返回值是String!類(lèi)型轰豆,那么是可以直接當(dāng)String來(lái)用;而現(xiàn)在齿诞,方法返回類(lèi)型如果為String!酸休,獲取到的返回值實(shí)際上是String?〉昏荆客觀上說(shuō)斑司,String!的返回值也是可以為nil的,所以如果在外部直接使用獲取的返回值,為nil的情況會(huì)直接導(dǎo)致crash宿刮。尤其是老舊的OC代碼互站,沒(méi)有_Nonnull或_Nullable修飾的返回值,在Swift中全部默認(rèn)為強(qiáng)制解包類(lèi)型僵缺,現(xiàn)在都要當(dāng)?類(lèi)型用了胡桃。
String!目前和String?最大共同點(diǎn)在于,如果當(dāng)前值是Optional("123")磕潮,那么在使用該值是翠胰,將都是String?;另外自脯,它們的區(qū)別就是之景,調(diào)對(duì)象方法或訪問(wèn)對(duì)象屬性時(shí),String!會(huì)直接以解包對(duì)象的方式去調(diào)膏潮,而String?仍然是可選鏈方法锻狗。詳細(xì)見(jiàn)下圖

Swift 3.0的可選類(lèi)型示例
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市焕参,隨后出現(xiàn)的幾起案子轻纪,更是在濱河造成了極大的恐慌,老刑警劉巖龟糕,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件桐磁,死亡現(xiàn)場(chǎng)離奇詭異悔耘,居然都是意外死亡讲岁,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)衬以,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)缓艳,“玉大人,你說(shuō)我怎么就攤上這事看峻〗滋裕” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵互妓,是天一觀的道長(zhǎng)溪窒。 經(jīng)常有香客問(wèn)我,道長(zhǎng)冯勉,這世上最難降的妖魔是什么澈蚌? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮灼狰,結(jié)果婚禮上宛瞄,老公的妹妹穿的比我還像新娘。我一直安慰自己交胚,他們只是感情好份汗,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布盈电。 她就那樣靜靜地躺著,像睡著了一般杯活。 火紅的嫁衣襯著肌膚如雪匆帚。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,829評(píng)論 1 290
  • 那天旁钧,我揣著相機(jī)與錄音卷扮,去河邊找鬼。 笑死均践,一個(gè)胖子當(dāng)著我的面吹牛晤锹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播彤委,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼鞭铆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了焦影?” 一聲冷哼從身側(cè)響起车遂,我...
    開(kāi)封第一講書(shū)人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎斯辰,沒(méi)想到半個(gè)月后舶担,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡彬呻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年衣陶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闸氮。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡剪况,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蒲跨,到底是詐尸還是另有隱情译断,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布或悲,位于F島的核電站孙咪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏巡语。R本人自食惡果不足惜翎蹈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捌臊。 院中可真熱鬧杨蛋,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至寇荧,卻和暖如春举庶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背揩抡。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工户侥, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人峦嗤。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓蕊唐,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親烁设。 傳聞我的和親對(duì)象是個(gè)殘疾皇子替梨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 因?yàn)橐Y(jié)局swift3.0中引用snapKit的問(wèn)題,看到一篇介紹Xcode8,swift3變化的文章,覺(jué)得很詳細(xì)...
    uniapp閱讀 4,405評(píng)論 0 12
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)装黑,斷路器副瀑,智...
    卡卡羅2017閱讀 134,633評(píng)論 18 139
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 3,783評(píng)論 1 10
  • 多線程、特別是NSOperation 和 GCD 的內(nèi)部原理恋谭。運(yùn)行時(shí)機(jī)制的原理和運(yùn)用場(chǎng)景糠睡。SDWebImage的原...
    LZM輪回閱讀 2,004評(píng)論 0 12
  • “人非圣賢孰能無(wú)過(guò)”當(dāng)我們做錯(cuò)了的時(shí)候就要學(xué)會(huì)說(shuō)出對(duì)不起三個(gè)字,無(wú)論是家人還是同事疚颊,一句對(duì)不起不僅可能會(huì)挽回一段...
    濰坊泰華DDM張娟閱讀 815評(píng)論 3 0