Swift 結(jié)構(gòu)體 與 類

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

一、結(jié)構(gòu)體 是值類型

二、結(jié)構(gòu)體的存儲(chǔ)位置

結(jié)構(gòu)體的存儲(chǔ)位置 根據(jù)不同情況來(lái)分
1、如果結(jié)構(gòu)體(值類型)在函數(shù)中創(chuàng)建 它存儲(chǔ)在棧空間
例如:

func testStruct(){
    struct Point {
        var x: Int = 0
        var y: Int = 0
    }
    var p = Point()
}

由于結(jié)構(gòu)體在  testStruct 函數(shù)中創(chuàng)建 所以他存儲(chǔ)在 ??臻g

2、 如果值類型在全局區(qū)創(chuàng)建的 它存儲(chǔ)在代碼區(qū)
例如:

import Foundation

struct Point {
    var x: Int
    var y: Int
}

var p = Point.init(x: 10, y: 10)

三、說(shuō)明 + 示例

在swift標(biāo)準(zhǔn)庫(kù)中。絕大數(shù)的公開(kāi)類都是結(jié)構(gòu)體。而枚舉和類只占很小一部分

比如 Bool、 Int 、Double、 String 、Array、 Dictionary

所有的結(jié)構(gòu)體 都有編譯器自動(dòng)生成的初始化器
編譯器會(huì)根據(jù)實(shí)際情況 可能會(huì)為結(jié)構(gòu)體生成多個(gè)初始化器
生成初始化器的宗旨是:保證所有成員都有初始值(這是秘訣 要記?。?/p>

例如下面的幾種類型
1、Point x 和 y 沒(méi)有初始值

struct Point {
    var x: Int
    var y: Int
}

//由于初始化器的宗旨是:保證所有成員都有初始值
// Point 中 的 x 和 y 都沒(méi)有初始值 
// 所以編譯器自動(dòng)給Point 生成一個(gè)兩個(gè)參數(shù)的初始化器

var p = Point.init(x: 10, y: 10)

2、Point1 x沒(méi)有初始值 y有初始值

struct Point1 {
    var x: Int
    var y: Int = 10
}

//由于初始化器的宗旨是:保證所有成員都有初始值
// Point1 中 的 x沒(méi)有初始值   y有初始值 
// 所以編譯器自動(dòng)給Point1 生成如下兩個(gè)初始化器

var p1 = Point1.init(x: 10, y: 30)
var p11 = Point1.init(x: 30)

3、Point2 x和y都有初始值

struct Point2 {
    var x: Int = 20
    var y: Int = 10
}

//由于初始化器的宗旨是:保證所有成員都有初始值
// Point2 中 的 x  和  y 都有初始值 
// 所以編譯器自動(dòng)給Point2 生成如下四個(gè)初始化器

var p21 = Point2.init(x: 0, y: 20)
var p22 = Point2.init(x:0)
var p23 = Point2.init(y:0)
var p24 = Point2.init()

4、Point3 x和y都為可選型 (因?yàn)榭蛇x型初始值 都為nil)

struct Point3 {
    var x: Int?
    var y: Int?
}

//由于初始化器的宗旨是:保證所有成員都有初始值
// Point3 中 的 x  和  y   都為可選型 
// 由于可選型都有默認(rèn)值 nil
// 所以編譯器自動(dòng)給Point3 生成如下四個(gè)初始化器

var p31 = Point3.init(x: 0, y: 20)
var p32 = Point3.init(x:0)
var p33 = Point3.init(y:0)
var p34 = Point3.init()

自定義初始化器

注意??:一旦定義了結(jié)構(gòu)體的初始化器 編譯器就不會(huì)幫助它生成其他的初始化器

例如

struct Point4 {
    var x: Int = 0
    var y: Int = 0
    init(x: Int,y: Int){
        self.x = x
        self.y = y
    }
}

//由于我們自定義了一個(gè)初始化器  所以編譯器就不會(huì)再為我們生成初始化器
//所以 我們 初始化Point4 只能用我們自己定義的
var p4 = Point4.init(x: 10, y: 20)

一、類 是引用類型 (指針類型)

類的定義和結(jié)構(gòu)體類似 但是編譯器不會(huì)為類自動(dòng)生成可傳入成員值的初始化器

注意??:
如果類的所有成員都在定義的時(shí)候指定了類初始值 編譯器就會(huì)為類生成無(wú)參的初始化器
成員的初始化就是在無(wú)參的初始化器中完成的
例如

class Point {
    var x: Int = 0
    var y: Int = 1
}

// 因?yàn)?類的所有成員都在定義的時(shí)候指定了類初始值
//所以編譯器為Point 自動(dòng)生成了一個(gè)初始化器

let p1 = Point.init()

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

在swift中 結(jié)構(gòu)體和類 都能定義方法
結(jié)構(gòu)體是值類型
枚舉也是值類型

類是引用類型(指針類型)

舉例說(shuō)明

struct Point {
    var x: Int = 3
    var y: Int = 4
}

class Size {
    var width = 1
    var hight = 2
}


func test(){
    var point = Point()
    var size = Size()
}

text 函數(shù)在??臻g的分布情況如下圖所示 (假設(shè)開(kāi)始地址是 0x10000)


text 函數(shù)在??臻g的分布.png

解析:
由于 text 是一個(gè)函數(shù) 所以他存儲(chǔ)在棧空間
??臻g 前16個(gè)字節(jié) 分別存放 Point (值類型)的兩個(gè)成員變量的值

后8個(gè)字節(jié) 存放的 是一個(gè)指針變量(也就是 size size是一個(gè)指針)

size 指針變量?jī)?nèi)存中存放的是 size對(duì)象內(nèi)存地址(這個(gè)地址是在堆空間 因?yàn)閟ize是一個(gè)對(duì)象 創(chuàng)建的時(shí)候需要 alloc 開(kāi)辟堆空間)

size對(duì)象的前 8個(gè)字節(jié) 存放的是 類型信息的地址 它指向size的元類 元類來(lái)存放類的一些信息(如:方法、類方法)

8--16個(gè)字節(jié) 存放的是 對(duì)象的引用計(jì)數(shù)
后面就是存放類的一些成員信息

值類型 與 引用類型的區(qū)別

值類型 賦值給 var、let 或者 給函數(shù)傳參 是直接將內(nèi)容拷貝一份 會(huì)產(chǎn)生全新的文件副本

修改 原數(shù)據(jù) 對(duì) 副本沒(méi)有任何影響
修給 副本 對(duì) 原數(shù)據(jù)沒(méi)有任何影響

注意??:
在Swift標(biāo)準(zhǔn)庫(kù)中,為了提升性能,String、Array、Dictionary、Set采取了Copy On Write的技術(shù) (也就是說(shuō) 只有在對(duì)其進(jìn)行修改的時(shí)候才會(huì)去深度拷貝 如果不修改僅僅是淺拷貝)
比如僅當(dāng)有“寫(xiě)”操作時(shí),才會(huì)真正執(zhí)行拷貝操作

對(duì)于標(biāo)準(zhǔn)庫(kù)值類型的賦值操作,Swift 能確保最佳性能,所有沒(méi)必要為了保證最佳性能來(lái)避免賦值

建議:不需要修改 盡量換成let

例如

var s1 = "Jack" 
var s2 = s1 
print(s1)
s2.append("_Rose")
print(s2)

當(dāng)代碼走到14行時(shí) s1 和 s2 他們倆指向的是同一塊內(nèi)存 如下圖所示

47E1DF5C72CCA51DE99C1AC111A55194.png

當(dāng)代碼走到16行時(shí) s1 和 s2 他們倆指向的是不同內(nèi)存 如下圖所示


A51727869D5DC2B9EACED04D55992885.png

原因是因?yàn)?s2 進(jìn)行了改寫(xiě) 所以就就調(diào)用 copy

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一. 結(jié)構(gòu)體 1. 結(jié)構(gòu)體簡(jiǎn)介 在 Swift 標(biāo)準(zhǔn)庫(kù)中,絕大多數(shù)的公開(kāi)類型都是結(jié)構(gòu)體,而枚舉和類只占很小一部分,...
    Imkata閱讀 707評(píng)論 0 2
  • 結(jié)構(gòu)體 在 Swift 標(biāo)準(zhǔn)庫(kù)中,絕大多數(shù)的公開(kāi)類型都是結(jié)構(gòu)體,而枚舉和類只占很小一部分 比如Bool、Int、D...
    蔣斌文閱讀 264評(píng)論 0 1
  • swift中,我們?cè)谝粋€(gè)文件中定義結(jié)構(gòu)體和類并實(shí)現(xiàn)他的接口。 基礎(chǔ)知識(shí) 結(jié)構(gòu)體和類的比較 相同點(diǎn): 屬性:保存數(shù)據(jù)...
    枯樹(shù)戀閱讀 1,551評(píng)論 0 0
  • 結(jié)構(gòu)體 在 Swift 標(biāo)準(zhǔn)庫(kù)中,絕大多數(shù)的公開(kāi)類型都是結(jié)構(gòu)體,而枚舉和類只占很小一部分 Bool、Int、Dou...
    一抹相思淚成雨閱讀 299評(píng)論 0 1
  • ??在Swift標(biāo)準(zhǔn)庫(kù)中,絕大多數(shù)的公開(kāi)類型都是結(jié)構(gòu)體,而枚舉和類之占一小部分,比如:Bool、Int、Doubl...
    Aliv丶Zz閱讀 765評(píng)論 0 0

友情鏈接更多精彩內(nèi)容