精通Swift(7)- 結(jié)構(gòu)體和類

結(jié)構(gòu)體

在Swift 標(biāo)準(zhǔn)庫中,絕大多數(shù)的公開類型都是結(jié)構(gòu)體号坡,而枚舉和類只占很小一部分?

比如Bool懊烤、Int、Double筋帖、 String奸晴、Array、Dictionary等常見類型都是結(jié)構(gòu)體

struct Date {

????var year: Int

????var month: Int

????var day: Int

}

var date = Date(year: 2019, month: 6, day: 23)

所有的結(jié)構(gòu)體都有一個(gè)編譯器自動(dòng)生成的初始化器(initializer日麸,初始化方法寄啼、構(gòu)造器、構(gòu)造方法)?

在第6行調(diào)用的代箭,可以傳入所有成員值墩划,用以初始化所有成員(存儲(chǔ)屬性,Stored Property)

結(jié)構(gòu)體的初始化器

編譯器會(huì)根據(jù)情況嗡综,可能會(huì)為結(jié)構(gòu)體生成多個(gè)初始化器乙帮,宗旨是:保證所有成員都有初始值

可選項(xiàng)都有個(gè)默認(rèn)值nil ?因此可以編譯通過

struct Point {

? ? var x: Int?

? ? var y: Int?

}

var p1 = Point(x: 10, y: 10)

var p2 = Point(y: 10)

var p3 = Point(x: 10)

var p4 = Point()

自定義初始化器:一旦在定義結(jié)構(gòu)體時(shí)自定義了初始化器,編譯器就不會(huì)再幫它自動(dòng)生成其他初始化器

窺探初始化器的本質(zhì)

以下2段代碼完全等效

? struct Point {

? ? var x: Int = 0

var y: Int = 0 }

var p = Point()

----------------

struct Point {

? ? var x: Int

? ? var y: Int

????init() { x=0 y=0

} }

var p = Point()

結(jié)構(gòu)體內(nèi)存結(jié)構(gòu)

struct Point {

? ? var x: Int = 0

var y: Int = 0

? ? var origin: Bool = false

}

print(MemoryLayout<Point>.size) // 17

print(MemoryLayout<Point>.stride) // 24

print(MemoryLayout<Point>.alignment) // 8

類?

類的定義和結(jié)構(gòu)體類似极景,但編譯器并沒有為類自動(dòng)生成可以傳入成員值的初始化器

結(jié)構(gòu)體與類的本質(zhì)區(qū)別

結(jié)構(gòu)體是值類型(枚舉也是值類型)察净,類是引用類型(指針類型)

? class Size {

? ? var width = 1

? ? var height = 2

}

struct Point {

? ? var x = 3

? ? var y = 4

}

func test() {

? ? var size = Size()

? ? var point = Point()

}

值類型的賦值操作

????在Swift標(biāo)準(zhǔn)庫中驾茴,為了提升性能,String氢卡、Array锈至、Dictionary、Set采取了Copy On Write的技術(shù)?

????比如僅當(dāng)有“寫”操作時(shí)译秦,才會(huì)真正執(zhí)行拷貝操作

????對于標(biāo)準(zhǔn)庫值類型的賦值操作峡捡,Swift 能確保最佳性能,所有沒必要為了保證最佳性能來避免賦值

????建議:不需要修改的筑悴,盡量定義成let

var s1 = "Jack"

var s2 = s1

s2.append("_Rose")

print(s1) // Jack

print(s2) // Jack_Rose

-----------------------

var a1 = [1, 2, 3]

var a2 = a1

a2.append(4)

a1[0] = 2

print(a1) // [2, 2, 3]

print(a2) // [1, 2, 3, 4]

--------------------

var d1 = ["max" : 10, "min" : 2]

var d2 = d1

d1["other"] = 7

d2["max"] = 12

print(d1) // ["other": 7, "max": 10, "min": 2]

print(d2) // ["max": 12, "min": 2]

引用類型

????引用賦值給var们拙、let或者給函數(shù)傳參,是將內(nèi)存地址拷貝一份 p類似于制作一個(gè)文件的替身(快捷方式阁吝、鏈接)砚婆,指向的是同一個(gè)文件。屬于淺拷貝(shallow copy)

class Size {

? ? var width: Int

var height: Int

init(width: Int, height: Int) {

? ? ? ? self.width = width

? ? ? ? self.height = height

? ? }

}

func test() {

var s1 = Size(width: 10, height: 20) var s2 = s1

}

s2.width = 11

s2.height = 22

// s1.width和s1.height是11 22

對象的堆空間申請過程

在Swift中求摇,創(chuàng)建類的實(shí)例對象射沟,要向堆空間申請內(nèi)存,大概流程如下 Class.__allocating_init()?

libswiftCore.dylib:_swift_allocObject_?

libswiftCore.dylib:swift_slowAlloc?

libsystem_malloc.dylib:malloc

在Mac与境、iOS中的malloc函數(shù)分配的內(nèi)存大小總是16的倍數(shù)

通過class_getInstanceSize可以得知:類的對象至少需要占用多少內(nèi)存

class Point? {

? ? var x = 11

? ? var test = true

????var y = 22 }

var p = Point()

class_getInstanceSize(type(of: p)) // 40

class_getInstanceSize(Point.self) // 40

引用類型的賦值操作

class Size {

? ? var width: Int

? ? var height: Int

? ? init(width: Int, height: Int) {

? ? ? ? self.width = width

? ? ? ? self.height = height

? ? }

}

var s1 = Size(width: 10, height: 20)

s1 = Size(width: 11, height: 22)

值類型验夯、引用類型的let

struct Point {? ? var x: Int? ? var y: Int} // ? 屬性不可改

class?Size?{ // 屬性可改

? ? var width: Int? ? var height: Int? ??

????????init(width: Int, height: Int) {

? ? ? ? self.width = width

? ? ? ? self.height = height

? ? }

}

嵌套類型

struct Poker {

? ? enum Suit : Character {

????????????case spades = "?", hearts = "?", diamonds = "?" , clubs = "?"}

????enum Rank : Int {

????????case two = 2, three, four, five, six, seven, eight, nine, ten

? ? ? ? case jack, queen, king, ace

? ? }

}

print(Poker.Suit.hearts.rawValue)

var suit = Poker.Suit.spades

suit = .diamonds

var rank = Poker.Rank.five

rank = .king

枚舉、結(jié)構(gòu)體摔刁、類都可以定義方法

一般把定義在枚舉挥转、結(jié)構(gòu)體、類內(nèi)部的函數(shù)共屈,叫做方法

方法占用對象的內(nèi)存么? ?不占用?

方法的本質(zhì)就是函數(shù)?

方法绑谣、函數(shù)都存放在代碼段

class Size {

? ? var width = 10

? ? var height = 10

? ? func show() {

????print("width=\(width), height=\(height)") }

}

let s = Size()

s.show() // width=10, height=10

-------------------------------

struct Point {

? ? var x = 10

? ? var y = 10

????func show() { print("x=\(x), y=\(y)")

} }

let p = Point()

p.show() // x=10, y=10

--------------------

enum PokerFace : Character {

? ??case spades = "?", hearts = "?", diamonds = "?", clubs = "?"

????func show() { print("x=\(x), y=\(y)")}?

}

let pf = PokerFace.hearts?

pf.show() // face is ?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市拗引,隨后出現(xiàn)的幾起案子借宵,更是在濱河造成了極大的恐慌,老刑警劉巖矾削,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件壤玫,死亡現(xiàn)場離奇詭異,居然都是意外死亡哼凯,警方通過查閱死者的電腦和手機(jī)欲间,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來断部,“玉大人猎贴,你說我怎么就攤上這事。” “怎么了她渴?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵达址,是天一觀的道長。 經(jīng)常有香客問我惹骂,道長苏携,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任对粪,我火速辦了婚禮,結(jié)果婚禮上装蓬,老公的妹妹穿的比我還像新娘著拭。我一直安慰自己,他們只是感情好牍帚,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布儡遮。 她就那樣靜靜地躺著,像睡著了一般暗赶。 火紅的嫁衣襯著肌膚如雪鄙币。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天蹂随,我揣著相機(jī)與錄音十嘿,去河邊找鬼。 笑死岳锁,一個(gè)胖子當(dāng)著我的面吹牛绩衷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播激率,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼咳燕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了乒躺?” 一聲冷哼從身側(cè)響起招盲,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嘉冒,沒想到半個(gè)月后曹货,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡健爬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年控乾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娜遵。...
    茶點(diǎn)故事閱讀 39,779評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蜕衡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情慨仿,我是刑警寧澤久脯,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站镰吆,受9級特大地震影響帘撰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜万皿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一摧找、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧牢硅,春花似錦蹬耘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至位岔,卻和暖如春如筛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抒抬。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工杨刨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瞧剖。 一個(gè)月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓拭嫁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親抓于。 傳聞我的和親對象是個(gè)殘疾皇子做粤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評論 2 354

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