Swift Runtime(1)-初探
阿新 • • 發佈:2020-06-24
#前言 本文介紹Swift Runtime機制.相信大家對於Objective-C裡的Class都或多或少有一些瞭解.即使沒有去研究過,也可能聽說過Class其實是結構體,結構體裡面含有isa,superClass這樣的說法.那麼本文研究的就是Swift類本質及其執行時原理.
#初探 首先新建一個Xcode專案,為了不讓其它因素幹擾,選擇Command Line Tool
生成專案的目錄結構非常簡單
先進入main.swift檔案檢視.可以看到檔案內容非常簡單,這就是選擇Command Line Tool的原因,不被其它因素幹擾// main.swift
// Runtime
//
// Created by XXX on 2020/4/19.
// Copyright © 2020 Runtime. All rights reserved.
//
import Foundation
print("Hello,World!")
複製程式碼
接下來刪掉除print("Hello,World")
之外包括註釋的所有程式碼,並在print("Hello,World")
加上斷點
接下來我們定義一個Person類,並且增加如下程式碼到print("Hello,World")
上方:
class Person {
}
var a = Person()
var b = Person()
var c = Person()
print("Hello,World!")
複製程式碼
然後讓我們執行,因為斷點的原因,程式會在print("Hello,World")
停住.可以看到a,b,c三個變數成功賦值了.
x/2gx <物件地址>
命令的意思是以指定格式輸出物件地址處的內容.先讓我們觀察一下輸出的第一段內容0x0000000100002108
,發現三個物件起始位置都是一樣的,讓人猜測是否是指明型別的資料.我們再來定義一個Animal型別驗證一下:
class Person {
}
class animal {
}
var a = Person()
var b = Person()
var c = Person()
var d = animal()
var e = animal()
var f = animal()
print ("Hello,World!")
複製程式碼
明顯發現a,c三個Person型別的起始位置為0x0000000100002198
,而d,e,f三個都為0x0000000100002228
與Person類的變數是不一樣的.相同型別的一樣,不同型別的不一樣,可以判斷起始位置就是類資訊資料所在處.
那至於後面一段內容0x0000000400000002
,0x0000000200000002
是什麼呢?讓我們繼續探究,將程式碼修改成如下,並像上面一樣列印物件內容:
class Person {
}
var a = Person()
print("Hello,World!")
複製程式碼
接下里我們再增加一句程式碼:var b = a
,並再次輸出物件內容:
class Person {
}
var a = Person()
var b = a
print("Hello,World!")
複製程式碼
第三次我們再增加:var c = a
,並再次輸出物件內容:
class Person {
}
var a = Person()
var b = a
var c = a
print("Hello,World!")
複製程式碼
三次結果,我們會發現第二段的內容一次變化為0x0000000200000002
->0x0000000400000002
->0x0000000600000002
,會發現有一個值會每次有規律的增加2.
而兩次增加的程式碼var b = a
var c = a
其實是對a變數的引用,每引用一次物件第二段的內容的某個值會增加2.這個看上去是不是很像我們熟悉的引用計數呢?
#總結
其實查閱Swift的原始碼及檔案,一個物件實際上是HeapObject結構體,結構如下:
struct HeapObject {
/// This is always a valid pointer to a metadata object.
HeapMetadata const *metadata;
InlineRefCounts refCounts
}
複製程式碼
其中metadata
是描述型別資訊的資料結構指標,而refCounts
如名稱所示,是引用計數的資料結構.
所以我們的初步研究完全能得到對應的結果,例項變數是HeapObject
結構體,並且儲存類資訊和自己的引用計數.接下來我們就會仔細研究一下這兩個metadata
和refCounts
.