一不见、Swift 構(gòu)建對(duì)象
對(duì)于 Objective-C
分為兩步 alloc 分配內(nèi)存 init 初始化 [[class alloc]init]
對(duì)于Swift
Swift 可以通過(guò)更簡(jiǎn)單的語(yǔ)法創(chuàng)建一個(gè)對(duì)象 Class()
下面創(chuàng)建一個(gè)簡(jiǎn)單的Swift 類分析一下
class Text {
var age:Int = 18
var name = "text"
let s: String?
init(_ s: String) {
self.s = s
//var mmm = Text("1111111111111111111")
}
}
var t = Text("sss")
sil分析
通過(guò)sil文件分析一下可以更容易理解Swift的這個(gè)語(yǔ)法
以下是編譯過(guò)后截圖
剛剛的代碼編譯好之后大概是這個(gè)樣子
以上發(fā)現(xiàn)關(guān)鍵字 @_hasStorage @_hasInitialValue 代表的是 存儲(chǔ)屬性 和 有默認(rèn)值的意思有時(shí)間可以了解下
根據(jù)sil文件自動(dòng)的注釋看到 Text Class 類型的 t 指針 編譯成了 "@s4main1tAA4TextCv" 代表 t
看下函數(shù)調(diào)用捂刺, 實(shí)例化 t 之前也是先調(diào)用了 alloc_global 方法 并傳入了 Text 類型先分配 (t 指針的)內(nèi)存 (alloc_stacck)
特別說(shuō)一下:
往下看有一個(gè)方法是創(chuàng)建 age 屬性的 忆肾, 特別提到是因?yàn)榭砂l(fā)現(xiàn) Swift 中Int 是 struct 這很重要棒口,例如以后使用的時(shí)候會(huì)發(fā)現(xiàn)一些問(wèn)題 Int("1.1")會(huì)失敗损敷,直接去結(jié)構(gòu)體中會(huì)發(fā)現(xiàn)只能傳入整形的字符串欧宜,否則返回的會(huì)是nil,這時(shí)候可能需要使用 Float 疾渣、 Double ..轉(zhuǎn)化篡诽,當(dāng)然直接點(diǎn)擊Int類型進(jìn)去也可以看見struct Int 一些特性
再往下看 會(huì)發(fā)現(xiàn)alloc_ 之后會(huì)調(diào)用 Text 的allocating_init() 方法
把 %10 和 %4 參數(shù)傳入,最后把返回的地址賦給%3
allocating_inti 的具體實(shí)現(xiàn):
sil 命令文檔:https://github.com/apple/swift/blob/main/docs/SIL.rst
以上可看出來(lái)其實(shí)Swift也是有alloc init 隱式調(diào)用的邏輯的
Swift alloc 的源碼榴捡,有興趣可以去看一下
通過(guò)以上可以發(fā)現(xiàn)Swift和objective 構(gòu)建class對(duì)象流程邏輯上沒有本質(zhì)上區(qū)別都是先malloc 再 init
HeapObject
不同于ObjectiveC 在內(nèi)存中存儲(chǔ)對(duì)象的結(jié)構(gòu)是objc_object 杈女,Swift 對(duì)象存儲(chǔ)的結(jié)構(gòu)是HeapObject結(jié)構(gòu),不過(guò)也不用過(guò)多擔(dān)心吊圾,兩個(gè)結(jié)構(gòu)內(nèi)容還是比較統(tǒng)一的
HeapObject 再往里面點(diǎn)
最后會(huì)發(fā)現(xiàn)有挺長(zhǎng)的一個(gè)繼承鏈达椰,把這個(gè)繼承鏈內(nèi)容整理起來(lái)就是:
保證了和OC混編的時(shí)候也可以互相調(diào)用
相比于objc_class ,HeapObject為什么這么多繼承鏈呢街夭?砰碴,因?yàn)镠eapObject kind屬性不止針對(duì)Class類型躏筏,struct板丽、enum、Optional...
refCount
也是一個(gè)類對(duì)象,存儲(chǔ)了引用計(jì)數(shù)埃碱、強(qiáng)應(yīng)用和無(wú)主引用猖辫、弱引用
二、聲明屬性
1砚殿、存儲(chǔ)屬性啃憎,let 常量、var變量(let聲明屬性就是只生成get方法不生成set方法)
2似炎、計(jì)算屬性辛萍,就是set、get方法
3羡藐、屬性觀察者贩毕,willSet、didSet(就是在賦值前后調(diào)用這兩個(gè)方法沒有啥玄學(xué)(addObserve不在此處使用))
4仆嗦、lazy 延遲存儲(chǔ)屬性
lazy var t:String = "ssss"
lazy關(guān)鍵字修飾必須有默認(rèn)值
只有第一次訪問(wèn)的時(shí)候才被賦值
不保證線程安全
雖然有默認(rèn)的值內(nèi)容辉阶,但是編譯完成之后默認(rèn)是實(shí)際是nil,等到第一次get或者set的時(shí)候才有值
5瘩扼、類型屬性
lazy不能保證線程安全谆甜,類型屬性可以
類型屬性是類屬性,也就是說(shuō)類屬性跟類實(shí)例沒有關(guān)系集绰,保證內(nèi)存中只有一根
用 static來(lái)聲明
static let ashare = Text()
但是實(shí)際上和OC聲明單例是一個(gè)原理规辱,都是調(diào)用 GCD 的dispatch_once,所以在Swift也用這種方法聲明單例(set方法并不是線程安全的)
6栽燕、可選值
感嘆號(hào)按摘、問(wèn)號(hào)標(biāo)記
三、結(jié)構(gòu)體
Swift結(jié)構(gòu)體在使用上與Class類似纫谅。例如:
Struct Text1{
var title = ""
var 1:String
func pringtTitle() {
print(title)
}
}
var s = Text1()
那Struct和Class的區(qū)別在于炫贤,結(jié)構(gòu)體屬性不需要必須有值,結(jié)構(gòu)體是值類型類是引用類型付秕,是的其他的沒有太大的區(qū)別兰珍,結(jié)構(gòu)體也可以遵序協(xié)議、聲明方法
另外需要注意的是如果在結(jié)構(gòu)體方法內(nèi)部修改結(jié)構(gòu)體的屬性需要使用muating來(lái)修飾(具體原因是結(jié)構(gòu)體內(nèi)部默認(rèn)參數(shù)self是常量询吴,mutating修飾之后變成了inout修飾進(jìn)而傳遞地址)
struct Text1 {
var title:String = ""
mutating func pringtTitle() {
title = "sdfghn"
print(title)
}
}
枚舉
enum Name:String {
case dos
case cc = "dsdsd"
case bb
case dd
}
Name.dou.RawValue
Swift 枚舉中枚舉原始值類型需要顯示的寫出來(lái)掠河,可以是字符串,字符猛计,或者任何整型值或浮點(diǎn)型值唠摹,可以通過(guò)RawValue(編譯之后生成的一個(gè)計(jì)算屬性)來(lái)訪問(wèn)
枚舉中可定義方法、計(jì)算屬性奉瘤、遵循協(xié)議勾拉、類型屬性
枚舉關(guān)聯(lián)值:
如果枚舉的值無(wú)法滿足信息的傳遞煮甥,例如我想傳遞的是我自定義的對(duì)象,可以使用關(guān)聯(lián)值藕赞,但是有了關(guān)聯(lián)值就不能定義原始值
枚舉的匹配:
同樣是switch成肘、if 判斷
閉包表達(dá)式
閉包就是一個(gè)捕獲了上下文常量、變量的函數(shù)斧蜕,其實(shí)可以簡(jiǎn)單理解為oc的block只是語(yǔ)法上不通双霍,下面是官方文檔給出的示例
和block一樣,閉包實(shí)際也是一個(gè)引用類型批销,可以當(dāng)做參數(shù)傳遞洒闸,可以聲明為屬性、捕獲屬性均芽、循環(huán)引用也是同理
和block有nsmalloc和你說(shuō)stackblock一樣顷蟀,閉包也分堆棧空間骡技,這也是逃逸閉包和非逃逸閉包的區(qū)別也就是說(shuō)閉包要在當(dāng)前聲明的作用域以外使用則需要聲明為逃逸閉包鸣个,逃逸閉包的內(nèi)存空間在堆上
閉包表達(dá)式
{(parameters) -> return type in
statements
}
沒有參數(shù)的話就是 {}
協(xié)議:
protocol Name {
var
func
}
1、swift 協(xié)議所有方法都必須實(shí)現(xiàn)也就是說(shuō)沒有 @optional 只能req
2布朦、協(xié)議可以當(dāng)做類型傳遞 不需要 id<protocol>delegate
擴(kuò)展
swift沒有分類的一說(shuō)囤萤,主要使用擴(kuò)展,不同于OC @interface swift kextension 可以提供方法是趴、方法實(shí)現(xiàn)涛舍、定義計(jì)算屬性,所以擴(kuò)展就可以滿足我們對(duì)于分類唆途、擴(kuò)展的需求
泛型
1富雅、占位類型名,通過(guò)實(shí)際傳入的數(shù)據(jù)來(lái)推斷
2肛搬、可以進(jìn)行類型約束 T: SomProtocol 要求傳入的泛型是遵循協(xié)議的
其他:類型轉(zhuǎn)換 as没佑、 is 、可選鏈温赔、下標(biāo)腳本蛤奢、訪問(wèn)限制
循環(huán) for (int i , i < , I++)被干掉了只剩for in,其他的循環(huán)語(yǔ)句條件判斷基本一致