目录概要1. 指针的认识1.1 指定类型指针1.2 未指定类型指针1.3 访问结构体实例对象2. 指针的常见绑定2.1 指针与内存空间的绑定(指向)(bindMemory)2.2 元
主要内容:
指针的认识
指针的常见绑定
指针分为两类,指定数据类型和未指定数据类型
区别:
代码:
运行结果:
说明:
代码:
<!--定义-->
@inlinable public func withUnsafePointer<T, Result>(to value: inout T, _ body: (UnsafePointer<T>) throws -> Result) rethrows -> Result
<!--使用1-->
var age = 10
let p = withUnsafePointer(to: &age) { $0 }
print(p)
<!--使用2-->
withUnsafePointer(to: &age){print($0)}
<!--使用3-->
//其中p1的类型是 UnsafePointer<Int>
let p1 = withUnsafePointer(to: &age) { ptr in
return ptr
}
说明:
访问属性:
直接修改:
直接在闭包中计算后将结果返回给属性
var age = 10
age = withUnsafePointer(to: &age) { ptr in
//返回Int整型值
return ptr.pointee + 12
}
print(age)
间接修改:
var age = 10
//分配容量大小,为8字节
let ptr = UnsafeMutablePointer<Int>.allocate(capacity: 1)
//初始化
ptr.initialize(to: age)
ptr.deinitialize(count: 1)
ptr.pointee += 12
print(ptr.pointee)
//释放
ptr.deallocate()
说明:
结构体:
struct CJLTeacher {
var age = 10
var height = 1.85
}
var t = CJLTeacher()
指针处理:
//分配两个CJLTeacher大小的空间
let ptr = UnsafeMutablePointer<CJLTeacher>.allocate(capacity: 2)
//初始化第一个空间
ptr.initialize(to: CJLTeacher())
//移动,初始化第2个空间
ptr.successor().initialize(to: CJLTeacher(age: 20, height: 1.75))
//访问方式一
print(ptr[0])
print(ptr[1])
//访问方式二
print(ptr.pointee)
print((ptr+1).pointee)
//访问方式三
print(ptr.pointee)
//successor 往前移动
print(ptr.successor().pointee)
//必须和分配是一致的
ptr.deinitialize(count: 2)
//释放
ptr.deallocate()
说明:
将指针指向某个内存空间,也就是绑定到这个内存空间上
定义:
struct HeapObject {
var kind: Int
var strongRef: UInt32
var unownedRef: UInt32
}
class CJLTeacher{
var age = 18
}
var t = CJLTeacher()
绑定:
//将t绑定到结构体内存中
//1、获取实例变量的内存地址,声明成了非托管对象
let ptr = Unmanaged.passUnretained(t as AnyObject).toOpaque()
//2、绑定到结构体内存,返回值是UnsafeMutablePointer<T>
let heapObject = ptr.bindMemory(to: HeapObject.self, capacity: 1)
//3、访问成员变量
print(heapObject.pointee.kind)
print(heapObject.pointee.strongRef)
print(heapObject.pointee.unownedRef)
说明:
元组和指针指向内存的数据类型不一样,就需要使用假定内存绑定
代码:
var tul = (10, 20)
//UnsafePointer<T>
func testPointer(_ p : UnsafePointer<Int>){
print(p)
}
withUnsafePointer(to: &tul) { (tulPtr: UnsafePointer<(Int, Int)>) in
//不能使用bindMemory,因为已经绑定到具体的内存中了
//使用assumingMemoryBound,假定内存绑定,目的是告诉编译器ptr已经绑定过Int类型了,不需要再检查memory绑定
testPointer(UnsafeRawPointer(tulPtr).assumingMemoryBound(to: Int.self))
}
说明:
举例:获取结构体的属性的指针
struct HeapObject {
var strongRef: UInt32 = 10
var unownedRef: UInt32 = 20
}
func testPointer(_ p: UnsafePointer<Int>){
print(p)
}
//实例化
var t = HeapObject()
//获取结构体属性的指针传入函数
withUnsafePointer(to: &t) { (ptr: UnsafePointer<HeapObject>) in
//1. 获取变量
let strongRef = UnsafeRawPointer(ptr) + MemoryLayout<HeapObject>.offset(of: \HeapObject.strongRef)!
//2. 传递strongRef属性的值
testPointer(strongRef.assumingMemoryBound(to: Int.self))
}
说明:
问题:
代码实现:
var age = 10
func testPointer(_ p: UnsafePointer<Int64>){
print(p)
}
let ptr = withUnsafePointer(to: &age) {$0}
ptr.withMemoryRebound(to: Int64.self, capacity: 1) { (ptr: UnsafePointer<Int64>) in
testPointer(ptr)
}
说明:
指针的内存管理需要手动管理
假定内存绑定和内存绑定的区别
需要注意对于指针类型指针,可以通过指针偏移来偏移内存大小,而对于未指定类型的指针,只能通过内存偏移来偏移内存大小
将一个指针绑定到内存中,其实就是指向到这个内存空间
三种绑定的区别
以上就是Swift 指针底层探索分析的详细内容,更多关于Swift 指针底层的资料请关注编程网其它相关文章!
--结束END--
本文标题: Swift 指针底层探索分析
本文链接: https://www.lsjlt.com/news/168295.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0