code_小马swift
目录
一、指针
1.为什么说指针是不安全的
2.指针类型
3.原始指针的使用
4.泛型指针的使用
5.内存绑定
二、内存管理
1.弱引用
2.Unowned
一、指针
1.为什么说指针是不安全的
-
在创建一个对象的时候,是需要在堆分配内存空间。但是这个内存空间的生命周期是有限的。如果我们使用指针指向这块内存空间,如果当前内存空间的生命周期结束了(
引用计数为0,系统回收内存空间),那么我们当前的指针就变成了未定义的行为了(野指针)。 -
:比如我们创建一个
count为10的数组,这个时候我们通过指针访问到了index = 11的位置,这个时候就越界了,访问了一个未知的内存空间。 -
,也是不安全的。
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这个结构体实际大小size是9个字节
由于结构体YGTeacher的对象内存分配字节对齐alignment是8个字节,
所以不足8字节的Bool类型就要补齐到8个字节(字节对齐原则),
所以当前的步长信息stride是16个字节
- 使用
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、advanced、deinitialize、deallocate要 成对儿 使用。
- 指针读取Macho中的属性名称
首先分享一个优化版machOView工具地址(烂苹果)MachOView2.6.1
5.内存绑定
二、内存管理

YGTeacher.jpeg
可变/不可变类型的指针
泛型指针的使用







网友评论