美文网首页
swift--指针与内存绑定

swift--指针与内存绑定

作者: Mjs | 来源:发表于2020-12-14 14:26 被阅读0次

指针

Swift中的指针分为两类, typed pointer指定数据类型指针,raw pinter未指定数据类型的指针(原⽣指针)

raw pinter在Swift中的表示是 UnsafeRawPointer
typed pointer在Swift中的表示是 UnsafePointer<T>

Swift Object-C 说明
unsafePointer<T> const T * 指针及所指向的内容都不可变
unsafeMutablePointer T * 指针及其所指向的内存内容均可变
unsafeRawPointer const void * 指针指向未知类型
unsafeMutableRawPointer void * 指针指向未知类型

RawPointer使用

//指针的内存管理是手动管理
//申请32字节内存空间,8字节对齐方式
let p = UnsafeMutableRawPointer.allocate(byteCount: 32, alignment: 8)

for i in 0..<4 {
    //advanced 前进字节
    //storeBytes 储存数据
    p.advanced(by: i*8).storeBytes(of: i+1, as: Int.self)
}
for i in 0..<4 {
    //读取数据
    let value = p.load(fromByteOffset: i*8, as: Int.self)
    print("index\(i),value:\(value)")
}
p.deallocate()

allocate来开辟内存空间

 @inlinable
  public static func allocate(
    byteCount: Int, alignment: Int
  ) -> UnsafeMutableRawPointer {
    var alignment = alignment
    if alignment <= _minAllocationAlignment() {
      alignment = 0
    }
    return UnsafeMutableRawPointer(Builtin.allocRaw(
        byteCount._builtinWordValue, alignment._builtinWordValue))
  }

Builtin是LLVM标准模块。

unsafePointer

@inlinable public func withUnsafePointer<T, Result>(to value: T, _ body: (UnsafePointer<T>) throws -> Result) rethrows -> Result

通过rethrows将结果向上级传递

var age = 10
let p = withUnsafePointer(to: &age) {
    //单一表达式可省略
    //ptr in return ptr
    $0
}
print(p.pointee)

p就是$0,代表UnsafePointer这个对象指针,p.pointee就是值

var age = 10
age = withUnsafePointer(to: &age) { ptr in
    return ptr.pointee + 12
}
print(age)
··········UnsafeMutablePointer
22

这个时候返回的就是闭包返回值。

UnsafeMutablePointer

var age = 10
withUnsafeMutablePointer(to: &age) { ptr in
    ptr.pointee += 10
}
print(p)

UnsafeMutablePointer的区别就是可以直接对原始对象进行修改。

struct Teacher {
    var age = 10
    var height = 1.85
}

var t = Teacher()

let ptr = UnsafeMutablePointer<Teacher>.allocate(capacity: 2)
ptr.initialize(to: Teacher())
ptr.advanced(by:1).initialize(to: Teacher(age: 18, height: 1.66))
print(ptr[0])
print(ptr[1])
print(ptr.successor().pointee)

//手动管理
ptr.deinitialize(count: 2)
ptr.deallocate()
··············
Teacher(age: 10, height: 1.85)
Teacher(age: 18, height: 1.66)
Teacher(age: 18, height: 1.66)

内存绑定

  • withMemoryRebound : 临时更改内存绑定类型
    -bindMemory(to: Capacity:) : 更改内存绑定的类型,如果之前没有绑定,那么就是⾸次绑定;如果绑 定过了,会被重新绑定为该类型。
  • assumingMemoryBound: 假定内存绑定,这⾥是告诉编译器:哥们我就是这种类型,你不要检查我 了。
withMemoryRebound

var age = 10
let ptr = withUnsafePointer(to: &age){$0}
ptr.withMemoryRebound(to: UInt64.self, capacity: 1) { (ptr: UnsafePointer<UInt64>) in
    print(ptr.pointee)
}
bindMemory

结合之前学过的


struct HeapObject {
    var kind: UnsafeRawPointer
    var strongref: UInt32
    var unownedRef:UInt32
}
struct _swift_class {
    var kind: UnsafeRawPointer
    var superClass: UnsafeRawPointer
    var cachedata1: UnsafeRawPointer
    var cachedata2: UnsafeRawPointer
    var data: UnsafeRawPointer
    var flags: UInt32
    var instanceAddressOffset: UInt32
    var instanceSize: UInt32
    var flinstanceAlignMask: UInt16
    var reserved: UInt16
    var classSize: UInt32
    var classAddressOffset: UInt32
    var description: UnsafeRawPointer
    
}
class Teacher {
    var age = 18
}
var t = Teacher()
//相当于OCheCF交互方式,__bridge 所有权转变,转为指针
//passUnretained非retain
let ptr = Unmanaged.passUnretained(t as AnyObject).toOpaque()
//bindMemory 重新绑定类型
let hep = ptr.bindMemory(to: HeapObject.self, capacity: 1)
let meta = hep.pointee.kind.bindMemory(to: _swift_class.self, capacity: 1)

print(meta.pointee)
···················
_swift_class(kind: 0x0000000100004140, superClass: 0x00007fff97884f98, cachedata1: 0x00007fff6c7cf3d0, cachedata2: 0x0000002000000000, data: 0x0000000101a0eed2, flags: 2, instanceAddressOffset: 0, instanceSize: 24, flinstanceAlignMask: 7, reserved: 0, classSize: 136, classAddressOffset: 16, description: 0x0000000100002be8)

这样我们就可以查看metadata.

assumingMemoryBound
var tul = (10,20)
func testPointer(_ p :UnsafePointer<Int>){
    print(p[0],p[1])
}
withUnsafePointer(to: &tul) {  (tulPtr : UnsafePointer<(Int,Int)>) in
    //assumingMemoryBound 假定类型 告诉编译器类型,不需要检查
    testPointer(UnsafeRawPointer(tulPtr).assumingMemoryBound(to: Int.self))
}
··············
10 20

直接获取地址。

内存绑定是不安全的,需要我们自己掌控

相关文章

  • swift--指针与内存绑定

    指针 Swift中的指针分为两类, typed pointer指定数据类型指针,raw pinter未指定数据类型...

  • swift指针&内存管理-内存绑定

    swift提供了3种不同的API来绑定/重新绑定指针 assumingMemoryBound(to:) bindM...

  • 慕课网-Linux C语言指针与内存-学习笔记

    Linux C语言指针与内存 工具与原理 指针 数组 字符串 堆内存与栈内存 gdb内存调试工具。 C语言中指针的...

  • 第五周Boolan

    对象模型 vptr(虚表指针) 和vtbl(虚函数表) 继承函数指的是继承调用权 而不是内存的大小 静态绑定与动态...

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

    目录 一、指针 1.为什么说指针是不安全的 2.指针类型 3.原始指针的使用 4.泛型指针的使用 5.内存绑定 二...

  • 智能指针和垃圾回收

    堆内存管理:智能指针与垃圾回收 显式内存管理 野指针 重复释放 内存泄漏 C++11 的智能指针 unique_p...

  • GeekBand.重学C++(4)

    关于 this 指针 调用父类的成员 非 const 成员中 const 成员中 动态绑定与静态绑定 绑定时期 动...

  • C语言——第四次笔记

    指针指针的定义指针的类型指针的指向内容指针的运算数组与指针指针与函数动态分配内存结构体文件读写头文件与实现文件实例...

  • C语言续

    指针指针的定义指针的类型指针的指向内容指针的运算数组与指针指针与函数动态分配内存结构体文件读写头文件与实现文件实例...

  • 疯狂的c指针

    前言 本期简要介绍指针、指针操作符以及指针如何与内存相互作用。 1.1 指针和内存 C程序在编译后,会以以下三种形...

网友评论

      本文标题:swift--指针与内存绑定

      本文链接:https://www.haomeiwen.com/subject/cucygktx.html