【四】Swift-指针&内存管理

code_小马swift

目录

一、指针

1.为什么说指针是不安全的

2.指针类型

3.原始指针的使用

4.泛型指针的使用

5.内存绑定


二、内存管理

1.弱引用

2.Unowned

一、指针

1.为什么说指针是不安全的

  • \underline{野指针:}在创建一个对象的时候,是需要在堆分配内存空间。但是这个内存空间的生命周期是有限的。如果我们使用指针指向这块内存空间,如果当前内存空间的生命周期结束了(引用计数为0,系统回收内存空间),那么我们当前的指针就变成了未定义的行为了(野指针)。
  • \underline{我们创建的内存空间是有边界的 }:比如我们创建一个count为10的数组,这个时候我们通过指针访问到了index = 11的位置,这个时候就越界了,访问了一个未知的内存空间。
  • \underline{指针类型与内存类型不一致 },也是不安全的。

2.指针类型

Swift中指针分为两大类:
typed pointer 指定数据类型的指针;
raw pointer未指定数据类型的指针(原生指针)。

基本上我们接触到的指针类型有以下几中

Swift Object-C 说明 类型
unsafePointer<T> const T * 指针及所指向的内容都不可变 typed pointer
unsafeMutablePointer<T> T * 指针及其所指向的内存内容均可变 typed pointer
unsafeRawPointer const void * 指针指向的内存区域未定 原生指针
unsafeMutableRawPointer void * 同上 原生指针
unsafeBufferPointer<T> typed pointer
unsafeMutableBufferPointer<T> typed pointer
unsafeRawBufferPointer 原生指针
unsafeMutableRawBufferPointer 原生指针

3.原始指针的使用

三个基本概念:内存大小size、步长信息stride、字节对齐alignment

struct YGTeacher {
    var age: Int = 18
    var haveCar: Bool = true
}
//内存大小
print(MemoryLayout<YGTeacher>.size)
//步长:当前指针需要移动的真实大小
print(MemoryLayout<YGTeacher>.stride)
//对齐
print(MemoryLayout<YGTeacher>.alignment)
  • stride(步长):
    如果在内存当中,我要存储几个连续的YGTeacher的实例,那这个步长信息指的是:
    从第一个YGTeacher实例到下一个YGTeacher实例,它所跨越的长度信息。

YGTeacher.jpeg

分析上图打印结果:
Int类型的age占了8个字节
Bool类型的haveCar占了1个字节
所以:YGTeacher这个结构体实际大小size9个字节
由于结构体YGTeacher的对象内存分配字节对齐alignment8个字节
所以不足8字节的Bool类型就要补齐到8个字节(字节对齐原则),
所以当前的步长信息stride16个字节

  • 使用Raw Pointer来存储4个整形的数据:
    这里我们需要选取的是 UnsafeMutableRawPointer
    如下图所示:
存储  :storeBytes
加载  :load
移动  :advanced
输出台信息.png
补充 storeBytes 存储方法

4.泛型指针的使用

  • 如下图:不可变指针-只读,指针和指针指向的地址都不可修改;
    可变类型的指针,指针和指针指向的内容都是可变的。


    可变/不可变类型的指针
  • 指定数据类型的可变指针

分配内存空间allocate、初始化变量initialize、
取消初始设置deinitialize、deallocate释放内存空间


泛型指针的使用
  • 我们可以通过以下方式来初始实话我们的指针
struct YGStruct {
    var age: Int
    var height: Double
}
//分配内存空间,连续存储5个结构体的大小、明确指针内存储的数据类型为 YGStruct
var tPtr = UnsafeMutablePointer<YGStruct>.allocate(capacity: 5)
//存储第一个内存地址,赋值
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]);
//取消初始化释放内存空间
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、advanceddeinitialize、deallocate要 成对儿 使用。

5.内存绑定

二、内存管理

1.弱引用

2.Unowned

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本文主要介绍swift中的指针 swift中的指针分为两类 typed pointer 指定数据类型指针,即 Un...
    辉辉岁月阅读 1,297评论 0 1
  • 本文系学习Swift中的指针操作详解的整理 默认情况下Swift是内存安全的,苹果官方不鼓励我们直接操作内存。但是...
    流火绯瞳阅读 15,255评论 2 28
  • Swift 进阶之路 文章汇总[https://www.jianshu.com/p/5fbedf309237] S...
    Style_月月阅读 5,519评论 7 9
  • 指针 Swift中指针分为两类: typed pointer:指定数据类型指针,UnsafePointer<T>,...
    YY323阅读 8,017评论 0 1
  • 本文主要介绍Swift中的指针 Swift中的指针主要分为两类 typed pointer 指定数据类型的指针,即...
    源本平凡阅读 3,304评论 0 0

友情链接更多精彩内容