swift 取消初始化()与解除分配()

mwkjh3gx  于 2023-01-04  发布在  Swift
关注(0)|答案(1)|浏览(144)

为什么下面的代码要求我手动使用unsafe_pointer.deinitialize(count: 1)来取消初始化示例?
如果我只使用unsafe_pointer.deallocate(),那么这个示例在内存中仍然是活动的,那么使用deallocate()的目的是什么呢?
对不起,因为我正试图学习MRC的第一次提前。

class Unsafe_Memory {
  var name = "Hello World"
  deinit {
    print("\(type(of: self)) is deinited and deallocated")
  }
}

let unsafe_pointer: UnsafeMutablePointer<Unsafe_Memory> = .allocate(capacity: 1)

unsafe_pointer.pointee = Unsafe_Memory()
dump(unsafe_pointer.pointee)

unsafe_pointer.pointee.name = "Changed"
dump(unsafe_pointer.pointee)

unsafe_pointer.deinitialize(count: 1)
unsafe_pointer.deallocate()
ddrv8njm

ddrv8njm1#

必须对任何非平凡类型调用deinitialize
平凡类型可以逐位复制,无需间接引用或引用计数操作。通常,不包含强或弱引用或其他形式的间接引用的原生Swift类型是平凡的,导入的C结构和枚举也是如此。复制包含非平凡类型值的内存只能使用类型化指针安全地完成。直接从非平凡类型复制字节,内存中的值不会生成有效副本,只能通过调用C API(如memmove())来完成。
调用deinitialize首先取消初始化该内存,但正如docs所述,“在调用deinitialize(count:)之后,内存未初始化,但仍绑定到Pointee类型”。
然后,通过调用deallocate()释放内存块,类似于C中的free()deallocate()只能在非平凡类型或未初始化的内存块上调用。
如果类型是平凡的,你就不必调用deinitialize。无论如何调用deinitialize可能是好的,以防你的类型在将来变得不平凡,并且调用它不应该花费你任何东西。
您可以尝试在不调用deallocate的情况下运行代码。deinit块仍将被执行,因为deinitialize将运行该块。但是,该内存块仍被占用,直到您调用deallocate时才会释放。

相关问题