1.Swift和Objective-C的聯(lián)系
- Swift與Objective-C共用同一套運行時環(huán)境
我們編寫程序,讓程序運行起來谋旦,被機器執(zhí)行的代碼并非全部是由我們自己來編寫的。需要同時運行很多預(yù)先寫好的支持性的代碼,才能讓我們自己的代碼運行起來。- Swift跟Objective-C編譯出的程序代碼運行在同一套運行環(huán)境上面蜕衡。Swift的類型可以橋接到Objective-C的類型,反之亦然设拟。Swift編寫的代碼可以調(diào)用Objective-C編寫的代碼慨仿,反之也一樣。
Objective-C之前積累下來的大量類庫纳胧,實現(xiàn)不用改寫Swift就可以直接調(diào)用镰吆。- 同一個工程,可以同時使用Swift和Objective-C
Objective-C在一端跑慕,Swift在另一端鼎姊,兩端經(jīng)中間文件進行橋接。橋接文件包含Objective-C的頭文件相赁,編譯時自動轉(zhuǎn)成Swift可以識別的形式。Swift就可以使用Objective-C的類和它的函數(shù)慰于。
在Swift的類中钮科,加上@objc(類名)
的字樣,Objective-C也可以使用Swift編寫的類婆赠。但Swift跟C++的相互調(diào)用绵脯,需要Objective-C來封裝。- Swift骨子里大多與Objective-C一樣
Objective-C出現(xiàn)過的絕大多數(shù)概念休里,比如引用記數(shù)蛆挫、ARC、屬性妙黍、協(xié)議悴侵、接口、初始化拭嫁、擴展類可免、命名參數(shù)抓于、匿名函數(shù)等,在Swift中繼續(xù)有效(可能只是換了個術(shù)語)浇借。- Swift大多數(shù)概念與Objective-C一樣捉撮,也有些概念在Objective-C找不到對應(yīng),比如泛型妇垢。Swift中將那種操作寫一次就可以作用多個類型的語法叫做Generics(泛型)巾遭。
2.Swift比Objective-C有什么優(yōu)勢?
- Swift 容易閱讀
不再需要行尾的分號闯估,以及if/else
語句中圍繞條件表達式的括弧灼舍。另外就是方法的調(diào)用不再互相嵌套成中括號[[[ ]]]
。Swift 中的方法和函數(shù)的調(diào)用使用行業(yè)內(nèi)標準的在一對括弧
內(nèi)使用逗號分隔的參數(shù)列表睬愤。這樣做的結(jié)果就是一種帶有簡化了句法和語法的更加干凈有表現(xiàn)力的語言片仿。- Swift 更易于維護
Swift 丟掉了對應(yīng)兩個文件的要求。 Xcode編譯器可以自動計算出以來并執(zhí)行增量構(gòu)建尤辱。如此砂豌,將頭文件 同實現(xiàn)文件相分離。把 Objective-C 頭文件(.h)
和實現(xiàn)文件(.m)
合并成了一個代碼文件(.swift)
- Swift 更加安全
Swift代碼中的可選類型使得一個nil可選值的可能性變得非常的明確, 這意味它能在你寫下一段糟糕的代碼時會生成一個編譯器錯誤. 這就建立了一種短程反饋的循環(huán)光督,可以讓程序員帶著目標去寫代碼. 問題在代碼被寫就時就可以被修復, 這大大節(jié)省了你要在修復有關(guān)來自 Objective-C 指針邏輯的bug時需要耗費的時間和金錢.- Swift 代碼更少
Swift 減少了重復性語句和字符串操作所需要的代碼量阳距。在 Objective-C 中, 使用文本字符串將兩塊信息組合起來的操作非常繁瑣。Swift 采用當代編程語言的特性结借,比如使用“+”
操作符將兩個字符串加到一起筐摘。
Swift中的類型系統(tǒng)減少了代碼語句的復雜性--作為編譯器可以理解的類型。比如船老,Objective-C要求程序員記住特殊字符標記(%s咖熟,%d,%@)
并且提供了一個用逗號分隔的變量來代替每個標記柳畔。Swift支持字符串插入馍管,這就消除了需要記住的標記和允許程序員直接插入變量到面向用戶的字符串中- Swift 速度更快
刪除遺留下來的C語言約定大大提升了引擎蓋之下Swift的性能, 進行計算密集型任務(wù)的性能上,Swift已經(jīng)逼近C++的表現(xiàn), 將近是OC運行速度的1.4倍.- 總結(jié): 使用 Swift薪韩,程序員只要維護原來一半量的代碼文件确沸,手動的代碼同步工作為零,標點輸入出錯的概率也遠遠低于以前 -- 這樣就能騰出更多的時間寫高質(zhì)量的代碼俘陷。通過使用可選類型 —— 一種針對返回或不返回值的編譯時安全機制罗捎,而返回值是同步操作、網(wǎng)絡(luò)失效時無效的用戶輸入以及數(shù)據(jù)驗證錯誤發(fā)生時普遍會遇到的問題拉盾。ARC 在 Swift 中對過程式 C 風格的代碼桨菜,還有蘋果公司 Cocoa 框架使用的面向?qū)ο蟠a都進行了統(tǒng)一。
3.Swift的內(nèi)存管理是怎樣的捉偏?
- Swift 使用自動引用計數(shù)(Automatic Reference Counting, ARC)來簡化內(nèi)存管理, 這種內(nèi)存管理方式相比GC而言雷激,對程序員的要求較高, 并且ARC比GC更容易引起編程錯誤替蔬,但卻比GC快。尤其在性能很重要的場合屎暇。
4.Swift支持面向過程編程嗎承桥?
- 它采用了 Objective-C 的命名參數(shù)以及動態(tài)對象模型,可以無縫對接到現(xiàn)有的 Cocoa 框架根悼,并且可以兼容 Objective-C 代碼凶异,支持面向過程編程和面向?qū)ο缶幊獭?/li>
5.舉例說明Swift里面有哪些是 Objective-C中沒有的?
- Swift引入了在Objective-C中沒有的一些高級數(shù)據(jù)類型挤巡,例如tuples(元組)剩彬,可以使你創(chuàng)建和傳遞一組數(shù)值。
- Swift還引入了可選項類型(Optionals)矿卑,用于處理變量值不存在的情況喉恋。可選項的意思有兩種:一是變量是存在的母廷,例如等于X轻黑,二是變量值根本不存在。Optionals類似于Objective-C中指向nil的指針琴昆,但是適用于所有的數(shù)據(jù)類型氓鄙,而非僅僅局限于類,Optionals 相比于Objective-C中nil指針更加安全和簡明业舍,并且也是Swift諸多最強大功能的核心抖拦。
6.Swift 是一門安全語言嗎?
- Swift是一門類型安全的語言舷暮,Optionals就是代表态罪。Swift能幫助你在類型安全的環(huán)境下工作,如果你的代碼中需要使用String類型下面,Swift的安全機制能阻止你錯誤的將Int值傳遞過來复颈,這使你在開發(fā)階段就能及時發(fā)現(xiàn)并修正問題。
7.為什么要在變量類型后面加個問號诸狭?
- 用來標記這個變量的值是可選的,一般用“君纫!”和“驯遇?”定義可選變量的區(qū)別:用“!”定的可選變量必須保證轉(zhuǎn)換能夠成功蓄髓,否則報錯叉庐,但定義的變量可以直接使用,不會封裝在option里会喝;而用“陡叠?”號定的可選變量即使轉(zhuǎn)換不成功本身也不會出錯玩郊,變量值為nil,如果轉(zhuǎn)換成功枉阵,要使用該變量進行計算時變量名后需要加“译红!”
8.什么是泛型,它們又解決了什么問題兴溜?
- 泛型是用來使代碼能安全工作侦厚。在Swift中,泛型可以在函數(shù)數(shù)據(jù)類型和普通數(shù)據(jù)類型中使用拙徽,例如類刨沦、結(jié)構(gòu)體或枚舉。
- 泛型解決了代碼復用的問題膘怕。有一種常見的情況想诅,你有一個方法,需要一個類型的參數(shù)岛心,你為了適應(yīng)另一種類型的參數(shù)還得重新再寫一遍這個方法来破。
比如,在下面的代碼中鹉梨,第二個方法是第一個方法的“克隆體”:
這段代碼能達到了目的讳癌,但是編譯的時候并不安全。它允許一個字符串和一個整型數(shù)據(jù)進行比較:
9. Swift 中定義常量和 Objective-C 中定義常量有什么區(qū)別存皂?
一般人會覺得沒有差別晌坤,因為寫出來好像也確實沒差別。
OC是這樣定義常量的: const int number = 0;
Swift 是這樣定義常量的:let number = 0
首先第一個區(qū)別旦袋,OC中用const
來表示常量骤菠,而 Swift 中用let
來判斷是不是常量。
上面的區(qū)別更進一步說疤孕,OC中const
表明的常量類型和數(shù)值是在 compilation time 時確定的商乎;而 Swift 中let
只是表明常量(只能賦值一次),其類型和值既可以是靜態(tài)的祭阀,也可以是一個動態(tài)的計算方法鹉戚,它們在 runtime 時確定的。
10. Swift 中 struct 和 class 什么區(qū)別专控?舉個應(yīng)用中的實例
struct 是值類型抹凳,class 是引用類型。
看過WWDC的人都知道伦腐,struct
是蘋果推薦的赢底,原因在于它在小數(shù)據(jù)模型傳遞和拷貝時比class
要更安全,在多線程和網(wǎng)絡(luò)請求時尤其好用。
我們來看一個簡單的例子:
class A {
var val = 1
}
var a = A()
var b = a
b.val = 2
此時 a 的 val 也被改成了 2幸冻,因為 a 和 b 都是引用類型粹庞,本質(zhì)上它們指向同一內(nèi)存。
解決這個問題的方法就是使用 struct:
struct A {
var val = 1
}
var a = A()
var b = a
b.val = 2
此時 A 是struct洽损,值類型庞溜,b 和 a 是不同的東西,改變 b 對于 a 沒有影響趁啸。
小結(jié):
- class是引用類型强缘,struct則是值類型
- class允許一個類繼承另一個類的特征
- 類型轉(zhuǎn)換允許在運行時檢查和解釋一個類實例的類型
11. Swift 到底是面向?qū)ο筮€是函數(shù)式的編程語言?
Swift 既是面向?qū)ο蟮牟桓担质呛瘮?shù)式的編程語言旅掂。
說 Swift 是 Object-oriented(面向?qū)ο?,是因為 Swift 支持類的封裝访娶、繼承商虐、和多態(tài),從這點上來看與 Java 這類純面向?qū)ο蟮恼Z言幾乎毫無差別崖疤。說 Swift 是函數(shù)式編程語言秘车,是因為 Swift 支持 map, reduce, filter, flatmap 這類去除中間狀態(tài)、數(shù)學函數(shù)式的方法劫哼,更加強調(diào)運算結(jié)果而不是中間過程叮趴。
12.不通過繼承,代碼復用(共享)的方式有哪些
- 為 class/struct/enum 添加extension
- protocol + extension
13.集合(Set) 獨有的方法有哪些权烧?
集合(Set)用來存儲相同類型并且沒有確定順序的值眯亦。
集合(Set)類型取交集、并集般码、差集妻率、補集這些數(shù)學中常用集合方法是獨有的
14. map、filter板祝、reduce 的用法
WHAT Map,Filter,Reduce是什么宫静?
map:
對數(shù)組中的每一個元素執(zhí)行函數(shù)操作,并返回一個新的數(shù)組券时。filter:
篩選數(shù)組中滿足傳入函數(shù)的元素孤里,并返回新數(shù)組。reduce:
傳入一個初值橘洞,再傳入一個函數(shù)捌袜,初值和數(shù)組中每一個元素都會被傳入函數(shù)計算結(jié)果,最終返回一個值震檩。
WHY 為什么要使用Map,Filter,Reduce?
- 方便:代碼量極少琢蛤,節(jié)省時間
- 簡潔:符合Swift語言風格,當你使用map抛虏,filter博其,reduct的代碼質(zhì)量會更好。但也需要在合適的場景中使用它們迂猴,不要指望用它們來解決任何問題慕淡。沒有放之四海而皆準的真理。
- 效率:數(shù)據(jù)比較大的時候沸毁,高階函數(shù)會比傳統(tǒng)實現(xiàn)更快峰髓,因為它可以并行執(zhí)行(如運行在多核上),除非真的需要更高定制版本的map息尺,reduce和filter携兵,否則可以一直使用它們以獲得更快的執(zhí)行速度。
HOW 怎么使用?
- 例(map):將示例數(shù)組搂誉,每個數(shù)字都加10徐紧,獲得一個新的數(shù)組。
//采用閉包的方式
var result = numberArray.map({($0) + 10})
print(result)
- 例(FlatMap):找出數(shù)組中大于2的數(shù)
filteredArray = numberArray.filter({$0 > 2})
print(filteredArray)
- 例(reduce):計算數(shù)組中所有數(shù)字的和炭懊,積
sum = numberArray.reduce(0, combine: {$0 + $1})
print(sum)
15.if let/guard let 使用場景
- guard語句來要求條件必須為真時并级,以執(zhí)行g(shù)uard語句后的代碼。
- guard守護有值,和if let相反 ,邏輯代碼少降低分支的層次, 通常判斷后有值就直接做邏輯處理
- if let 使用它解決Optional對象解包時產(chǎn)生空對象的處理
16.defer常用與需要配對出現(xiàn)的代碼侮腹,比如文件的打開與關(guān)閉嘲碧,加鎖與解鎖
- defer常用與需要配對出現(xiàn)的代碼,比如文件的打開與關(guān)閉父阻,加鎖與解鎖.
- 對應(yīng)OC中是黑魔法之一
__attribute__(cleanup(...))
愈涩。
17.String 與 NSString 的關(guān)系與區(qū)別
- String是結(jié)構(gòu)體,NSString是類至非,這是它們的根本區(qū)別钠署。
- Swift 中,結(jié)構(gòu)體struct是值類型荒椭,String是結(jié)構(gòu)體谐鼎,所以也是值類型;
- 類class是引用類型趣惠,NSString是類狸棍,所以也是引用類型.
18.throws 和 rethrows 的用法與區(qū)別
- 1、throw異常味悄,這表示這個函數(shù)可能會拋出異常草戈。不管作為參數(shù)的閉包是否拋出異常
- 2、rethrow異常侍瑟,這表示這個函數(shù)本身不會拋出異常唐片,但假設(shè)作為參數(shù)的閉包拋出了異常丙猬。那么它會把異常繼續(xù)拋上去。比如
func map<T>(@noescape transform: (Generator.Element) throws -> T) rethrows -> [T]
19.try费韭、try茧球?、和 try星持!是什么意思抢埋?
- try 出現(xiàn)異常處理異常
- try? 不處理異常,返回一個可選值類型,出現(xiàn)異常返回nil
- try! 不讓異常繼續(xù)傳播,一旦出現(xiàn)異常程序停止,類似NSAssert()
20. 什么時候使用 final
- final關(guān)鍵字在大多數(shù)的編程語言中都存在,表示不允許對其修飾的內(nèi)容進行繼承或者重新操作督暂。Swift中揪垄,final關(guān)鍵字可以在class、func和var前修飾逻翁。所以饥努,當確定這個類、函數(shù)是最終實現(xiàn)(類不被繼承八回,屬性方法不被override)時候使用final保證代碼安全肪凛。
- 具體情況如下:
(1)類或者方法的功能確實已經(jīng)完備了
這種通常是一些輔助性質(zhì)的工具類或者方法,特別那種只包含類方法而沒有實例方法的類辽社。比如MD5加密類這種伟墙,算法都十分固定,我們基本不會再繼承和重寫滴铅。
(2)避免子類繼承和修改造成危險
有些方法如果被子類繼承重寫會造成破壞性的后果戳葵,導致無法正常工作,則需要將其標為final加以保護汉匙。
(3)為了讓父類中某些代碼一定會執(zhí)行
父類的方法如果想要其中一些關(guān)鍵代碼在繼承重寫后仍必須執(zhí)行(比如狀態(tài)配置拱烁、認證等)。我們可以把父類的方法定義成final噩翠,同時將內(nèi)部可以繼承的部分剝離出來戏自,供子類繼承重寫。
下面通過一段代碼演示:
class Parent {
final func method1() {
//權(quán)限驗證(必須執(zhí)行)
//.....
method2()
//下面是日志記錄(必須執(zhí)行)
//..........
}
func method2(){
//父類的實現(xiàn)
//......
}
}
class Child : Parent {
//只能重寫父類的method2方法伤锚,不能重寫method1方法
override func method2() {
//子類的實現(xiàn)
//......
}
}
21.open 擅笔、 public 、fileprivate 屯援、 private 的區(qū)別
- (1) private 只允許在當前類中調(diào)用猛们,不包括 Extension
private 現(xiàn)在變?yōu)榱苏嬲乃接性L問控制
用 private 修飾的方法不可以被代碼域之外的地方訪問- (2) fileprivate 其修飾的屬性或者方法只能在當前的 Swift 源文件里可以訪問。 即在同一個文件中狞洋,所有的 fileprivate 方法屬性都是可以訪問到的弯淘。
- (3) public 修飾的屬性或者方法可以在其他作用域被訪問
但不能在重載 override 中被訪問 ,也不能在繼承方法中的 Extension 中被訪問.- (4) open 修飾的屬性或者方法可以在其他作用域被訪問 ,修飾的屬性或者方法可以在其他作用域被繼承或重載 override
從高到低排序如下:open > public > fileprivate > private
22.dynamic framework 和 static framework 的區(qū)別是什么
- 動態(tài)庫文件名后綴:.dylib和.framework; 靜態(tài)庫文件名后綴:.a和.framework
- 靜態(tài)庫:鏈接時,靜態(tài)庫會被完整地復制到可執(zhí)行文件中吉懊,被多次使用就有多份冗余拷貝
- 系統(tǒng)動態(tài)庫:鏈接時不復制庐橙,程序運行時由系統(tǒng)動態(tài)加載到內(nèi)存假勿,供程序調(diào)用,系統(tǒng)只加載一次态鳖,多個程序共用废登,節(jié)省內(nèi)存
23. Swift 中定義常量和 Objective-C 中定義常量有什么區(qū)別?
- 一般人會覺得沒有差別郁惜,因為寫出來好像也確實沒差別。
- OC是這樣定義常量的:
const int number = 0
- Swift 是這樣定義常量的:
let number = 0
- 首先第一個區(qū)別甲锡,OC中用 const 來表示常量兆蕉,而 Swift 中用 let 來判斷是不是常量。
上面的區(qū)別更進一步說缤沦,OC中 const 表明的常量類型和數(shù)值是在編譯時(compilation time)
確定的虎韵;而 Swift 中let
只是表明常量(只能賦值一次),其類型和值既可以是靜態(tài)的缸废,也可以是一個動態(tài)的計算方法包蓝,它們在runtime
時確定的。
本文轉(zhuǎn)載于其它網(wǎng)站企量,僅供學習使用测萎!