【四】Swift-指針&內(nèi)存管理

code_小馬swift

目錄

一、指針

1.為什么說指針是不安全的

2.指針類型

3.原始指針的使用

4.泛型指針的使用

5.內(nèi)存綁定


二、內(nèi)存管理

1.弱引用

2.Unowned

一、指針

1.為什么說指針是不安全的

  • \underline{野指針:}在創(chuàng)建一個對象的時候,是需要在堆分配內(nèi)存空間。但是這個內(nèi)存空間的生命周期是有限的。如果我們使用指針指向這塊內(nèi)存空間,如果當(dāng)前內(nèi)存空間的生命周期結(jié)束了(引用計數(shù)為0,系統(tǒng)回收內(nèi)存空間),那么我們當(dāng)前的指針就變成了未定義的行為了(野指針)。
  • \underline{我們創(chuàng)建的內(nèi)存空間是有邊界的 }:比如我們創(chuàng)建一個count為10的數(shù)組,這個時候我們通過指針訪問到了index = 11的位置,這個時候就越界了,訪問了一個未知的內(nèi)存空間。
  • \underline{指針類型與內(nèi)存類型不一致 },也是不安全的。

2.指針類型

Swift中指針分為兩大類:
typed pointer 指定數(shù)據(jù)類型的指針;
raw pointer未指定數(shù)據(jù)類型的指針(原生指針)。

基本上我們接觸到的指針類型有以下幾中

Swift Object-C 說明 類型
unsafePointer<T> const T * 指針及所指向的內(nèi)容都不可變 typed pointer
unsafeMutablePointer<T> T * 指針及其所指向的內(nèi)存內(nèi)容均可變 typed pointer
unsafeRawPointer const void * 指針指向的內(nèi)存區(qū)域未定 原生指針
unsafeMutableRawPointer void * 同上 原生指針
unsafeBufferPointer<T> typed pointer
unsafeMutableBufferPointer<T> typed pointer
unsafeRawBufferPointer 原生指針
unsafeMutableRawBufferPointer 原生指針

3.原始指針的使用

三個基本概念:內(nèi)存大小size、步長信息stride、字節(jié)對齊alignment

struct YGTeacher {
    var age: Int = 18
    var haveCar: Bool = true
}
//內(nèi)存大小
print(MemoryLayout<YGTeacher>.size)
//步長:當(dāng)前指針需要移動的真實大小
print(MemoryLayout<YGTeacher>.stride)
//對齊
print(MemoryLayout<YGTeacher>.alignment)
  • stride(步長):
    如果在內(nèi)存當(dāng)中,我要存儲幾個連續(xù)的YGTeacher的實例,那這個步長信息指的是:
    從第一個YGTeacher實例到下一個YGTeacher實例,它所跨越的長度信息。

YGTeacher.jpeg

分析上圖打印結(jié)果:
Int類型的age占了8個字節(jié)
Bool類型的haveCar占了1個字節(jié)
所以:YGTeacher這個結(jié)構(gòu)體實際大小size9個字節(jié)
由于結(jié)構(gòu)體YGTeacher的對象內(nèi)存分配字節(jié)對齊alignment8個字節(jié),
所以不足8字節(jié)的Bool類型就要補齊到8個字節(jié)(字節(jié)對齊原則),
所以當(dāng)前的步長信息stride16個字節(jié)

  • 使用Raw Pointer來存儲4個整形的數(shù)據(jù):
    這里我們需要選取的是 UnsafeMutableRawPointer
    如下圖所示:
存儲  :storeBytes
加載  :load
移動  :advanced
輸出臺信息.png
補充 storeBytes 存儲方法

4.泛型指針的使用

  • 如下圖:不可變指針-只讀,指針和指針指向的地址都不可修改;
    可變類型的指針,指針和指針指向的內(nèi)容都是可變的。


    可變/不可變類型的指針
  • 指定數(shù)據(jù)類型的可變指針

分配內(nèi)存空間allocate、初始化變量initialize、
取消初始設(shè)置deinitialize、deallocate釋放內(nèi)存空間


泛型指針的使用
  • 我們可以通過以下方式來初始實話我們的指針
struct YGStruct {
    var age: Int
    var height: Double
}
//分配內(nèi)存空間,連續(xù)存儲5個結(jié)構(gòu)體的大小、明確指針內(nèi)存儲的數(shù)據(jù)類型為 YGStruct
var tPtr = UnsafeMutablePointer<YGStruct>.allocate(capacity: 5)
//存儲第一個內(nèi)存地址,賦值
tPtr[0] = YGStruct(age: 15, height: 160.0)
tPtr[1] = YGStruct(age: 21, height: 175.0)
tPtr[2] = YGStruct(age: 25, height: 181.0)
print("①",tPtr[0],"\n1=",tPtr[1],"\n2=",tPtr[2],"\n3=",tPtr[3],"\n4=",tPtr[4]);
//取消初始化釋放內(nèi)存空間
tPtr.deinitialize(count: 5)
tPtr.deallocate()

  • 我們還可通過以下方式初始化指針
struct YGStruct_tow {
    var age = 20
    var height = 1.83
}

let p = UnsafeMutablePointer<YGStruct_tow>.allocate(capacity: 2)
p.initialize(to: YGStruct_tow())
p.advanced(by: MemoryLayout<YGStruct_tow>.stride).initialize(to: YGStruct_tow(age: 25, height: 1.83))

p.deinitialize(count: 2)
p.deallocate()

記住 initialize、advanced、deinitialize、deallocate要 成對兒 使用。

5.內(nèi)存綁定

二、內(nèi)存管理

1.弱引用

2.Unowned

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

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

  • 本文主要介紹swift中的指針 swift中的指針分為兩類 typed pointer 指定數(shù)據(jù)類型指針,即 Un...
    輝輝歲月閱讀 193評論 0 1
  • 本文系學(xué)習(xí)Swift中的指針操作詳解的整理 默認(rèn)情況下Swift是內(nèi)存安全的,蘋果官方不鼓勵我們直接操作內(nèi)存。但是...
    流火緋瞳閱讀 15,368評論 2 28
  • Swift 進(jìn)階之路 文章匯總[http://www.itdecent.cn/p/5fbedf309237] S...
    Style_月月閱讀 1,697評論 7 9
  • 指針 Swift中指針分為兩類: typed pointer:指定數(shù)據(jù)類型指針,UnsafePointer<T>,...
    YY323閱讀 3,047評論 0 1
  • 本文主要介紹Swift中的指針 Swift中的指針主要分為兩類 typed pointer 指定數(shù)據(jù)類型的指針,即...
    源本平凡閱讀 545評論 0 0

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