Swift 類與結構體(2)

2022-09-14 04:42:13 字數 3212 閱讀 5652

swift-類與結構體(2)

在這裡, 我們從函式的角度來出發看類與結構體

一、函式相關的修飾符

1.mutating修飾符

前提:在swift中class 和struct中都可以定義方法,但是在預設情況下值型別的屬性是無法被自身的例項方法修改的

struct

student

mutating func move(x deltax:double,y deltay:double)

}

mutating修飾符可以允許值型別屬性被修改,那麼,我們從sil中間**的角度來看這兩個的區別(第一行是第乙個函式生成的,第二行是mutating函式生成的):

1 function_ref @$s4main7shpointv3sumyyf : $@convention(method) (shpoint) ->() 

2 function_ref @$s4main7shpointv6moveby6deltax0e1yysd_sdtf : $@convention(method) (double, double, @inout shpoint) -> ()

當不使用mutating時,函式引數傳遞的是shpoint ,而使用mutating時,函式引數傳遞的是@inout shpoint。那麼這兩者又什麼區別呢?我們就需要了解一下inout這個修飾符

2.inout修飾符

inout即輸入輸出引數,他可以使函式內部修改外部實參的值(當函式執行之後,age的值需要在函式結束後依然保持改變)。

通過打斷點,我們進入到組合語言中發現,在呼叫結構體的方法時,其實是直接拿到函式的位址進行呼叫的。

三、類的方法

我們新建乙個 swift 專案,需要注意的是,一定要用真機跑,因為我們的 ios 程式都是要裝到手機上的,而手機的架構目前基本都是 arm64 的架構(我這裡是在模擬器上的)。

定義乙個shperson型別,呼叫方法,打個斷點,來看一下 swift 類的方法在彙編的呼叫情況(bl,blr都表示跳轉到某指令,blr表示無返回值)。

在上面的彙編**中我們發現,其中的三次blr即為三次呼叫teach函式的過程,從彙編**中我們發現,其實teach的呼叫過程是通過類拿到例項物件,同時拿到metadata的位址後通過記憶體平移的方式從而拿到函式位址再進行呼叫的。那麼我們這些連續的函式位址又放在**呢?此時我們就需要了解一下虛函式表了。

1.虛函式表(vtable)

在swift物件組成中有乙個metadata,這個結構體中有個typedescriptor屬性,這個屬性是對類的乙個詳細的描述,在對這個屬性的查詢過程中可以發現,其內部有乙個addvtable函式,在這個函式的實現中有這樣一段**:

在這裡,計算offset(結構體中的成員變數所有記憶體大小之和)之後,呼叫了addint32()函式去計算新增方法到虛函式表的偏移量,最後再通過 for 迴圈,新增函式的指標。 總的來說:函式表新增函式的形式就是追加到陣列的末尾。所以呢,函式表是按順序連續儲存類的方法的指標。

四、machoview來分析類的方法儲存

1.mach-o檔案

mach-o(mach obejct)檔案實際上是mac以及ios上的可執行檔案的格式,mach-o檔案的結構如下所示:

2.mach-o檔案如何開啟

首先,我們需要現在xcode中生成當前專案的projects檔案(

swift5_types 這裡存放的是結構體、列舉、類的descriptor,那麼我們可以在 swift5_types 這裡找到類的descriptor的位址資訊。 右側展示位址資訊。

前面的四個位元組90 fb ff ff就是 類 的descriptor資訊(ios 屬於小端模式,所以90 fb ff ff要從右邊往左讀)

五、extension修飾符

我們先通過乙個例子來看看帶有extension修飾符的方法是怎麼呼叫的?(彙編需要在真機的arm64架構上才能顯示)

class

student

}extension student

}class

viewcontroller: uiviewcontroller

}

這樣做的目的是為了優化,如果把extension修飾的方法在加入到函式表中需要進一步的考慮方法的儲存位置,索引等等,但是如果我們直接靜態派發就可以避免這些操作啦。

因此,對於extension排程的方法都是靜態派發的。 

六、函式內聯

函式內聯是一種編譯器優化的方式,它通過使用方法的內容來替換直接呼叫該方法,從而優化效能。

Swift教程 類與結構體

swift 中類於結構體 swift中結構體與類既相似,又有不同。相似點 可以儲存變數 儲存函式 不同點 結構體不支援繼承,類支援 結構體是引用型別,類引用型別 定義 結構體定義 struct somestructure 類定義 class someclass2.例項化變數 let somereso...

Swift 類與結構體(1)

一 類與結構體 在這裡,我們主要 在swift中類與結構體之間的相同與不同,以及在我們平時使用的過程中應該如何選擇使用。1 結構體的特性 2 類特性 類是一種引用型別,他分配在堆區 不連續,第乙個成員的位址和類的首位址不一致 中,也就是說乙個類型別的變數不是直接儲存具體的例項物件,而是儲存當前具體例...

swift與結構體

struct resolution 所有結構體都有乙個自動生成的成員逐一構造器,用於初始化新結構體例項中成員的屬性 let vga resolution width 640,height 480 let someresolution resolution println vga.width prin...