Swift 是蘋果在2014年推出的面向?qū)ο箝_發(fā)的語言,用來撰寫OS X 和 iOS 應(yīng)用程序的強類型語言。目前越來越多公司用 Swift 完成。這里整理了一些常問到的 Swift 面試問題。
摘錄與以下一些網(wǎng)站:
淺談Swift和OC的區(qū)別
Swift 基本使用
Objective-C 和 Swift 面試題
非常感謝上面網(wǎng)站的博主
以后持續(xù)更新這個文章。
(一)Swift 與 Objective-C 的聯(lián)系與區(qū)別?
Swift和Objective-C 共用一套運行時環(huán)境,Swift 的類型可以橋接到Objective-C(下面我簡稱OC),反之亦然。兩者可以互相引用混合編程。
其次就是,OC 之前積累的很多類庫,在 Swift 中大部分依然可以直接使用,當然,Swift3之后,一些語法改變了很多,不過還是有跡可循的。OC出現(xiàn)過的絕大多數(shù)概念,比如引用計數(shù)、ARC、屬性、協(xié)議、接口、初始化、擴展類、命名參數(shù)、匿名函數(shù)等,在Swift中繼續(xù)有效(可能最多換個術(shù)語)。Swift大多數(shù)概念與OC一樣。當然Swift也多出了一些新興概念,這些在OC中是沒有的,比如范型、元組等。
(二)Swift 比 Objective-C 有什么優(yōu)勢?
- Swift 容易閱讀,語法和文件結(jié)構(gòu)簡易化。
- Swift 更易于維護,文件分離后結(jié)構(gòu)更清晰。
- Swift 更加安全,它是類型安全的語言。
- Swift 代碼更少,簡潔的語法,可以省去大量冗余代碼。
- Swift 速度更快,運算性能更高。
(三)Swift目前存在的缺點
- 版本不穩(wěn)定,之前升級Swift3大動刀,苦了好多人。
- 使用人數(shù)比例偏低,目前還是OC的天下。
- 社區(qū)的開源項目偏少,畢竟OC獨大好多年,很多優(yōu)秀的類庫都不支持Swift,不過這種狀況正在改變,現(xiàn)在有好多優(yōu)秀的Swift的開源類庫了。
- 公司使用的比例不高,很多公司以穩(wěn)為主,還是在使用OC開發(fā),很少一些在進行混合開發(fā),更少一些是純Swift開發(fā)。
- 偶爾開發(fā)中遇到的一些問題,很難查找到相關(guān)資料,這是一個弊端。
- 純Swift的運行時和OC有本質(zhì)區(qū)別,一些OC中運行時的強大功能,在純Swift中變無效了。
- 對于不支持Swift的一些第三方類庫,如果非得使用,只能混合編程,利用橋接文件實現(xiàn)。
(四)Swift 相比 Objective-C 獨有的語法
范圍運算符
a...b 表示 [a,b] 包括a和b 。 (如3...5 就是范圍取3,4,5)
a..<b 表示 [a,b) 包括a,不包括b 。 (如3...5 就是范圍取3,4)
常見的如for循環(huán):for i in 0...9{}獨有的元組類型
元組(tuples)把多個值組合成一個復合值。元組內(nèi)的值可以使任意類型,并不要求是相同類型。eg:
var value = (Int,String) = (x:15,y:"abc")
- swift中使用let定義常量,var定義變量
使用常量,更加安全,不能夠被修改,在需要對對象進行修改的時候 只能用var修飾. - if let 、 guard let 的用法
縮減代碼量,安全處理數(shù)據(jù)邏輯。
(五)Swift 相比 Objective-C 細節(jié)使用區(qū)別
- swift不分.h和.m文件 ,一個類只有.swift一個文件,所以整體的文件數(shù)量比起OC有一定減少。
- swift句尾不需要分號 ,除非你想在一行中寫三行代碼就加分號隔開。
- swift數(shù)據(jù)類型都會自動判斷 , 只區(qū)分變量var 和常量let
- 強制類型轉(zhuǎn)換格式不同 OC強轉(zhuǎn):(int)a Swift強轉(zhuǎn):Int(a)
- 關(guān)于BOOL類型更加嚴格 ,Swift不再是OC的非0就是真,而是true才是真false才是假
- swift的 循環(huán)語句中必須加{} 就算只有一行代碼也必須要加
- swift的switch語句后面可以跟各種數(shù)據(jù)類型了 ,如Int、字符串都行,并且里面不用寫break(OC好像不能字符串)
- swift if后的括號可以省略: if a>b {},而OC里 if后面必須寫括號。
- swift打印 用print("") 打印變量時可以 print("(value)"),不用像OC那樣記很多%@,d%等。
- Swift3的【Any】可以代表任何類型的值,無論是類、枚舉、結(jié)構(gòu)體還是任何其他Swift類型,這個對應(yīng)OC中的【id】類型。
(六)Swift 是面向?qū)ο筮€是函數(shù)式的編程語言?
Swift 既是面向?qū)ο蟮?,又是函?shù)式的編程語言。
說 Swift 是面向?qū)ο蟮恼Z言,是因為 Swift 支持類的封裝、繼承、和多態(tài),從這點上來看與 Java 這類純面向?qū)ο蟮恼Z言幾乎毫無差別。
說 Swift 是函數(shù)式編程語言,是因為 Swift 支持 map, reduce, filter, flatmap 這類去除中間狀態(tài)、數(shù)學函數(shù)式的方法,更加強調(diào)運算結(jié)果而不是中間過程。
(七)請說明并比較以下關(guān)鍵詞:Open, Public, Internal, File-private, Private
Swift 有五個級別的訪問控制權(quán)限,從高到底依次為比如 Open, Public, Internal, File-private, Private。
他們遵循的基本原則是:高級別的變量不允許被定義為低級別變量的成員變量。比如一個 private 的 class 中不能含有 public 的 String。反之,低級別的變量卻可以定義在高級別的變量中。比如 public 的 class 中可以含有 private 的 Int。
- Open 具備最高的訪問權(quán)限。其修飾的類和方法可以在任意 Module 中被訪問和重寫;它是 Swift 3 中新添加的訪問權(quán)限。
- Public 的權(quán)限僅次于 Open。與 Open 唯一的區(qū)別在于它修飾的對象可以在任意 Module 中被訪問,但不能重寫。
- Internal 是默認的權(quán)限。它表示只能在當前定義的 Module 中訪問和重寫,它可以被一個 Module 中的多個文件訪問,但不可以被其他的 Module 中被訪問。
- File-private 也是 Swift 3 新添加的權(quán)限。其被修飾的對象只能在當前文件中被使用。例如它可以被一個文件中的 class,extension,struct 共同使用。
- Private 是最低的訪問權(quán)限。它的對象只能在定義的作用域內(nèi)使用。離開了這個作用域,即使是同一個文件中的其他作用域,也無法訪問。
(八)請說明并比較以下關(guān)鍵詞:strong, weak, unowned
Swift 的內(nèi)存管理機制與 Objective-C一樣為 ARC(Automatic Reference Counting)。它的基本原理是,一個對象在沒有任何強引用指向它時,其占用的內(nèi)存會被回收。反之,只要有任何一個強引用指向該對象,它就會一直存在于內(nèi)存中。
- strong 代表著強引用,是默認屬性。當一個對象被聲明為 strong 時,就表示父層級對該對象有一個強引用的指向。此時該對象的引用計數(shù)會增加1。
- weak 代表著弱引用。當對象被聲明為 weak 時,父層級對此對象沒有指向,該對象的引用計數(shù)不會增加1。它在對象釋放后弱引用也隨即消失。繼續(xù)訪問該對象,程序會得到 nil,不虧崩潰
- unowned 與弱引用本質(zhì)上一樣。唯一不同的是,對象在釋放后,依然有一個無效的引用指向?qū)ο?,它不?Optional 也不指向 nil。如果繼續(xù)訪問該對象,程序就會崩潰。
加分回答:
- weak 和 unowned 的引入是為了解決由 strong 帶來的循環(huán)引用問題。簡單來說,就是當兩個對象互相有一個強指向去指向?qū)Ψ剑@樣導致兩個對象在內(nèi)存中無法釋放(詳情請參考第3章第3節(jié)第8題)。
weak 和 unowned 的使用場景有如下差別:
- 當訪問對象時該對象可能已經(jīng)被釋放了,則用 weak。比如 delegate 的修飾。
- 當訪問對象確定不可能被釋放,則用 unowned。比如 self 的引用。
- 實際上為了安全起見,很多公司規(guī)定任何時候都使用 weak 去修飾。
(九)在Swift和Objective-C的混編項目中,如何在Swift文件中調(diào)用Objective-C文件中已經(jīng)定義的方法?如何在Objective-C文件中調(diào)用Swift文件中定義的方法?
- Swift中若要使用Objective-C代碼,可以在ProjectName-Bridging-Header.h里添加Objective-C的頭文件名稱,Swift文件中即可調(diào)用相應(yīng)的Objective-C代碼。一般情況Xcode會在Swift項目中第一次創(chuàng)建Objective-C文件時自動創(chuàng)建ProjectName-Bridging-Header.h文件。
- Objective-C中若要調(diào)用Swift代碼,可以導入Swift生成的頭函數(shù)ProjectName-Swift.h來實現(xiàn)。
- Swift文件中若要規(guī)定固定的方法或?qū)傩员┞督oObjective-C使用,可以在方法或?qū)傩郧凹由螥objc來聲明。如果該類是NSObject子類,那么Swift會在非private的方法或?qū)傩郧白詣蛹由螥objc。
(十)用Swift 將協(xié)議(protocol)中的部分方法設(shè)計成可選(optional),該怎樣實現(xiàn)?
@optional 和 @required 是 Objective-C 中特有的關(guān)鍵字。
Swift中,默認所有方法在協(xié)議中都是必須實現(xiàn)的。而且,協(xié)議里方法不可以直接定義 optional。先給出兩種解決方案:
- 在協(xié)議和方法前都加上 @objc 關(guān)鍵字,然后再在方法前加上 optional 關(guān)鍵字。該方法實際上是把協(xié)議轉(zhuǎn)化為Objective-C的方式然后進行可選定義。示例如下:
@objc protocol SomeProtocol {
func requiredFunc()
@objc optional func optionalFunc()
}
- 用擴展(extension)來規(guī)定可選方法。Swift中,協(xié)議擴展(protocol extension)可以定義部分方法的默認實現(xiàn),這樣這些方法在實際調(diào)用中就是可選實現(xiàn)的了。示例如下:
protocol SomeProtocol {
func requiredFunc()
func optionalFunc()
}
extension SomeProtocol {
func optionalFunc() {
print(“Dumb Implementation”)
}
}
Class SomeClass: SomeProtocol {
func requiredFunc() {
print(“Only need to implement the required”)
}
}
(十一)swift中,如何阻止一個方法屬性,屬性,下標被子類改寫?
在類的定義中使用final關(guān)鍵字聲明類、屬性、方法和下標。final聲明的類不能被繼承,final聲明的屬性、方法和下標不能被重寫。
(十二)swift中,實現(xiàn)一個將整形數(shù)組全部轉(zhuǎn)化成對應(yīng)的字符串數(shù)組(eg: [1,2,3,4,5] -> ["1","2","3","4","5"])
var sampleArray: [Int] = [1,2,3,4,5]
sampleArray.map {
String($0)
}
//["1", "2", "3", "4", "5"]
(十三)swift中,關(guān)鍵字 guard 和 defer 的用法
guard也是基于一個表達式的布爾值去判斷一段代碼是否該被執(zhí)行。與if語句不同的是,guard只有在條件不滿足的時候才會執(zhí)行這段代碼。
guard let name = self.text else { return }
defer的用法是,這條語句并不會馬上執(zhí)行,而是被推入棧中,直到函數(shù)結(jié)束時才再次被調(diào)用。
defer {
//函數(shù)結(jié)束才調(diào)用
}