1.@objc
作用:把函數(shù)或?qū)傩跃幾g進項目-Swift文件中酸役,這樣在OC調(diào)用Swift的方法的時候就不會報找不到這個方法了
->1.Swift 的靜態(tài)語言特性痕届,每個函數(shù)的調(diào)用在編譯期間就可以確定。因此在編譯完成后可以檢測出沒有被調(diào)用到的 swift 函數(shù),優(yōu)化刪除后可以減小最后二進制文件的大小置谦。而OC是動態(tài)語言,函數(shù)的調(diào)用在運行時才能確定有沒有被調(diào)用亿傅。所以為了避免OC找不到swift的函數(shù)媒峡,添加 @objc 的方法表示這個方法是被OC調(diào)用的,這樣swift在編譯的時候葵擎,雖然檢測到這個函數(shù)暫時沒有被調(diào)用谅阿,但是也不會被優(yōu)化刪除,編譯進項目-Swift文件中。
->2.類前加上@objcMembers签餐,那么它及其子類寓涨、擴展里的方法都會隱式的加上@objc,@nonobjc可以去掉@objc氯檐,
->3.Selector中調(diào)用的方法需要在方法前聲明@objc戒良,目的是允許這個函數(shù)在“運行時”通過 Objective-C 的消息機制調(diào)用
->4.協(xié)議的方法可選時,協(xié)議和可選方法前要用@objc,(這個不知道為什么冠摄,哪位大神給指點下)
2. _
忽略參數(shù)名
3.Struct和Class的區(qū)別
http://www.reibang.com/p/34f253cb19d4
->類是引用類型糯崎,結構體為值類型
->結構體不支持繼承
->值類型被賦予給一個變量,常量或者被傳遞給一個函數(shù)的時候河泳,其值會被拷貝
->引用類型在被賦予到一個變量沃呢,常量或者被傳遞到一個函數(shù)時,其值不會被拷貝拆挥,因此引用的是已存在的實例本身而不是其拷貝
4.Swift比Objective-C有什么優(yōu)勢薄霜?
->Swift速度更快,運算性能更高
->Swift語法簡單易讀竿刁,代碼更少黄锤,更加清晰,易于維護
->Swift更加安全食拜,它是類型安全的語言
->Swift泛型鸵熟,結構體,枚舉都很強大
->Swift便捷的函數(shù)式編程
->Swift 類型判斷
5.Swift是面向?qū)ο筮€是函數(shù)式編程語言?
->Swift即是面向?qū)ο蟮母旱椋质呛瘮?shù)式的編程語言
->說Swift是面向?qū)ο蟮恼Z言流强,是因為Swift支持類的封裝,繼承和多態(tài)
->說Swift是函數(shù)式編程語言呢呻待,是因為Swift支持map,reduce打月,filter,flatmap這類去除中間狀態(tài),數(shù)學函數(shù)式的方法蚕捉,更加強調(diào)運算結果而不是中間過程
6.dynamic framework 和 static framework 的區(qū)別是什么奏篙?
->靜態(tài)庫和動態(tài)庫,靜態(tài)庫是每一個程序單獨打包一份迫淹,而動態(tài)庫則是多個程序之間共享秘通,
->靜態(tài)庫和動態(tài)庫是相對編譯期和運行期的:靜態(tài)庫在程,序編譯時會被鏈接到目標代碼中,程序運行時將不再更改靜態(tài)庫敛熬;而動態(tài)庫在程序編譯時并不會被鏈接到目標代碼中肺稀,只是在程序運行時才被載入,因此在程序運行期間還需要動態(tài)庫的存在
靜態(tài)庫好處:
模塊化,分工合作应民,提高了代碼的復用以及核心技術的保密程度
避免少量改動經(jīng)常導致大量的重復編譯連接
也可以重用话原,注意不是共享使用
動態(tài)庫好處:
使用動態(tài)庫夕吻,可以將最終可執(zhí)行文件體積縮小,將整個應用程序分模塊繁仁,團隊合作涉馅,進行分工,影響比較小
使用動態(tài)庫改备,多個應用程序共享內(nèi)存中的同一份庫文件控漠,節(jié)省資源
使用動態(tài)庫,可以不重新編譯連接可執(zhí)行程序的前提下悬钳,更新動態(tài)庫文件達到更新應用程序的目的
不同點:
靜態(tài)庫在連接時,會被完整的復制到可執(zhí)行文件中偶翅,如果多個APP都使用了同一個靜態(tài)庫默勾,那么每個App都會拷貝一份,缺點是浪費內(nèi)存聚谁。類似于定義一個基本變量母剥,使用該基本變量是是新復制了一份數(shù)據(jù),而不是原來定義的
動態(tài)庫不會復制形导,只有一份环疼,程序運行時動態(tài)加載到內(nèi)存中,系統(tǒng)個只會加載一次朵耕,多個程序共享一份炫隶,節(jié)約內(nèi)存,類似于使用變量的內(nèi)存地址一樣阎曹,使用的是同一個變量
共同點:靜態(tài)庫和動態(tài)庫都是閉源庫伪阶,只能拿來滿足某個功能的使用,不會暴露內(nèi)部具體的代碼信息
7.Swift值類型的寫時復制
->只有當一個結構體發(fā)生寫入行為時才會有復制行為
->在結構體內(nèi)部用一個引用類型來存儲實際的數(shù)據(jù)处嫌,在不進行寫入操作的普通傳遞過程中栅贴,都是將內(nèi)部的reference的引用計數(shù)+1,在進行寫入操作時熏迹,對內(nèi)部的reference做一次copy操作用來存儲新的數(shù)據(jù)檐薯,防止和之前的reference產(chǎn)生意外的數(shù)據(jù)共享
->swift中提供該[]函數(shù),他能檢查一個類的實例是不是唯一的引用注暗,如果是坛缕,我們就不需要對該結構體實例進行復制,如果不是友存,說明對象被不同的結構體共享祷膳,這是對他進行更改就需要進行復制
8.defer的用法
->使用defer代碼塊來表示在函數(shù)返回前,函數(shù)中最后執(zhí)行的代碼屡立,無論函數(shù)是否會跑出錯誤直晨,這段代碼都將執(zhí)行
->defer語句塊中的代碼搀军,會在當前作用于結束前調(diào)用,每當一個作用于結束勇皇,就進行該作用域defer執(zhí)行
->defer執(zhí)行的順序為逆序(棧式)
->defer中捕獲的變量的值是可以進行更改的
9.inout輸入輸出參數(shù)
->函數(shù)參數(shù)默認是常量罩句,試圖從函數(shù)主題內(nèi)部更改函數(shù)參數(shù)的值會導致編譯時錯誤,這意味著您不能錯誤地更改參數(shù)的值敛摘,如果您希望函數(shù)修改參數(shù)的值门烂,并且希望這些更改在函數(shù)調(diào)用結束后仍然存在,請將該參數(shù)定義為輸入輸出參數(shù)
->您可以通過將inout關鍵詞放在參數(shù)類型的前面來編寫輸入輸出參數(shù)兄淫,一個在出參數(shù)具有傳遞的值中屯远,有函數(shù)修改的功能,并將該部分送回出的功能來替代原來的值捕虽,
->您只能將變量作為輸入輸出參數(shù)的參數(shù)傳遞慨丐。您不能將常量或文字值作為參數(shù)傳遞,因為無法修改常量和文字泄私。當您將一個與號(&)作為變量傳入in-out參數(shù)時房揭,將它放在變量名的前面,以表明該變量可以被函數(shù)修改
->其本質(zhì)是將指向的參數(shù)的指針晌端,傳入進去了
10.什么是高階函數(shù)
->一個函數(shù)如果可以以某一個函數(shù)作為參數(shù)捅暴,或者是返回值,那么這個函數(shù)就稱之為高階函數(shù)
11.static和calss的區(qū)別
->在Swift中static和class都表示“類型范圍作用域”的關鍵詞咧纠,在所有類中,我們可以使用過static來描述類型作用域蓬痒,class是專門用來修飾class類型的
1.static可以修飾屬性和方法,
?? ->所有修飾的屬性和方法不能夠被重寫
?? ->static修飾的類方法和屬性包含final關鍵字的特性惧盹,重寫會報錯
2.class修飾方法和屬性
??? ->我們同樣可以使用class修飾方法和計算屬性乳幸,但是不能夠修飾存儲屬性
??? ->類方法和計算屬性都是可以被重寫的,可以使用class關鍵字也可以是static
12.訪問修飾符
Swift有5個級別的訪問控制權限,從高到低依次Open,Public,internal,fileprivate,private
子類的訪問權限不能比父類的訪問權限大
open:可以被任何類使用和繼承
public:可以背任何人訪問钧椰,但是其他module中不可以被重寫和繼承粹断,而module內(nèi)可以被重寫和繼承
internal:(默認訪問級別,internal修飾符可寫可不寫)
internal訪問級別所修飾的屬性或方法在源代碼所在的整個模塊都可以訪問嫡霞。如果是框架或者庫代碼瓶埋,則在整個框架內(nèi)部都可以訪問,框架由外部代碼所引用時诊沪,則不可以訪問如果是App代碼养筒,也是在整個App代碼,也是在整個App內(nèi)部可以訪問
fileprivate:fileprivate訪問級別所修飾的屬性或者方法在當前的Swift源文件里可以訪問
private:private訪問級別所修飾的屬性或者方法只能在當前類里訪問端姚。
13.Strong晕粪,weak,unowned
Swift的內(nèi)存管理機制與Object-C一樣為ARC渐裸,它的基本原理是巫湘,一個對象在沒有任何強指針引用指向它是装悲,其占用的內(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)存中無法釋放
weak 和 unowned 的使用場景有如下差別:
->當訪問對象時該對象可能已經(jīng)被釋放了,則用 weak梯捕。比如 delegate 的修飾
->當訪問對象確定不可能被釋放厢呵,則用 unowned。比如 self 的引用
->實際上為了安全起見傀顾,很多公司規(guī)定任何時候都使用 weak 去修飾
->weak的對象霞掺,在block塊內(nèi)再次獲取值時可能為nil,相當于變成了一個可選值禀崖,調(diào)用屬性或者方法需要加上?或者強制解析!,但是強制解析在對象已經(jīng)被釋放了時肯定會造成強解錯誤,導致程序崩潰
->unowned的對象脱羡,在block塊內(nèi)再次獲取值時依然是對象本身,只是該對象可能被釋放了梦湘,因此調(diào)用者必須保證在執(zhí)行block塊時該對象一定依然存在税娜,不然調(diào)用對象的方法時會造成崩潰
14.Swift為什么將String,Array婉徘,Dictionary設計成值類型漠嵌?
->值類型相比引用類型咐汞,最大的優(yōu)勢在于內(nèi)存使用的高效。值類型在棧上操作献雅,引用類型在堆身上操作碉考,棧上的操作僅僅是單個指針的上下移動,而堆上的操作則牽涉到合并挺身,移位侯谁,重新鏈接等,也就是說swift這樣設計章钾,大幅減少了堆上的內(nèi)存分配和回收的次數(shù)墙贱,同時copy-on-write又將值傳遞和復制的開銷降到了最低
->String,Array,Dictionary設計成值類型,也是為了線程安全考慮贱傀,通過swift的let設置惨撇,使得這些數(shù)據(jù)達到真正意義上的不變,它從根本上解決了多線程中內(nèi)存訪問和操作順序的問題
->設計成值類型可以提升API的靈活度府寒,例如通過實現(xiàn)Collection這樣的協(xié)議魁衙,我們可以遍歷String,使得整個開發(fā)更加靈活高效
15.閉包是引用類型嗎
閉包是引用類型株搔,如果一個閉包被分配給一個變量剖淀,這個變量復制給另一個變量,那么他們引用的是同一個閉包纤房,他們的捕捉列表也會被復制
16.Swift? mutating關鍵字的使用
類是引用類型纵隔,而結構體和枚舉是值類型,默認情況下炮姨,不能在其實例方法中修改值類型的屬性捌刮,為了修改值類型的屬性,必須在實例方法中使用mutating關鍵字舒岸,使用此關鍵字绅作,你的方法將能夠更改屬性的值,并在方法實現(xiàn)結束時將其寫回到原始結構
1.純Swift類的函數(shù)調(diào)用已經(jīng)不再是Objective-c的運行時發(fā)消息吁津,而是類似C++的vtable棚蓄,在編譯時就確定了調(diào)用哪個函數(shù),所以沒法通過runtime獲取方法碍脏、屬性
2.TestSwiftVC繼承自UIViewController梭依,基類為NSObject,而Swift為了兼容Objective-C典尾,凡是繼承自NSObject的類都會保留其動態(tài)性役拴,所以我們能通過runtime拿到他的方法。(表示這個類可以被OC使用)
3.可以知道@objc是用來將Swift的API導出給Objective-C和Objective-C runtime使用的钾埂,如果你的類繼承自Objective-c的類(如NSObject)將會自動被編譯器插入@objc標識
4.純Swift類沒有動態(tài)性河闰,但在方法科平、屬性前添加dynamic修飾可以獲得動態(tài)性。 繼承自NSObject的Swift類姜性,其繼承自父類的方法具有動態(tài)性瞪慧,其他自定義方法、屬性需要加dynamic修飾才可以獲得動態(tài)性部念。
若方法的參數(shù)弃酌、屬性類型為Swift特有、無法映射到Objective-C的類型(如Character儡炼、Tuple)妓湘,則此方法、屬性無法添加dynamic修飾(會編譯錯誤), dynamic破壞swift的靜態(tài)化 Swift類在Objective-C中會有模塊前綴
5.所有運行時方法都依賴TypeEncoding乌询,也就是method_getTypeEncoding返回的結果榜贴,他指定了方法的參數(shù)類型以及在函數(shù)調(diào)用時參數(shù)入棧所要的內(nèi)存空間,沒有這個標識就無法動態(tài)的壓入?yún)?shù)(比如testReturnVoidWithaId: Optional("v24@0:8@16") Optional("v")妹田,表示此方法參數(shù)共需24個字節(jié)唬党,返回值為void,第一個參數(shù)為id鬼佣,第二個為selector初嘹,第三個為id),而Character和Tuple是Swift特有的沮趣,無法映射到OC的類型,更無法用OC的typeEncoding表示坷随,也就沒法通過runtime獲取了