【问题标题】:How to find out the memory area of an "optional" in swift?如何快速找出“可选”的内存区域?
【发布时间】:2021-08-04 15:59:21
【问题描述】:

我正在研究 CoW。 我知道在数组和字典的底层,CoW 可以工作。

为了检查这一点,我通过打印查看了内存区域。

var array1 = [1,2,3] 
array1.withUnsafeBufferPointer { (point) in
    print(point)      // 0x00006000006080e0
}
var array2 = array1 //  0x00006000006080e0
array2.append(4)   // 0x0000600002351ba0 <- changed

如何查看可选类型的内存区域?在我观看的会议上,作者说在可选的引擎盖下,CoW 也可以工作,我想看看。

.withUnsafeBufferPointer - 对于可选类型不起作用!

var optionalInt: Int?
optionalInt = 1                 // memory area?
var optionalInt2 = optionalInt // memory area?
optionalInt2 = 2              // memory area?

【问题讨论】:

    标签: swift optional copy-on-write


    【解决方案1】:

    您需要使用withUnsafePointer(to:)

    var optionalInt: Int?
    print("optionalInt = \(optionalInt)")
    withUnsafePointer(to: optionalInt, { pointer in
        print("optionalInt: \(pointer)")
    })
    optionalInt = 1
    print("optionalInt = \(optionalInt)")
    var optionalInt2 = optionalInt
    print("optionalInt2 = \(optionalInt)")
    withUnsafePointer(to: optionalInt2, { pointer in
        print("optionalInt2: \(pointer)")
    })
    optionalInt2 = 2
    print("optionalInt2 = \(optionalInt)")
    

    输出:

    optionalInt = nil

    optionalInt: 0x00007ffee58ede90

    optionalInt = 可选(1)

    optionalInt2 = 可选(1)

    optionalInt2: 0x00007ffee58ede28

    optionalInt2 = 可选(1)

    【讨论】:

    • 我认为我在文档方面真的很糟糕。你是怎样找到它的?为未来提供建议。
    • @errorka 我知道它的存在,所以不必寻找它。但是,如果你查看withUnsafePointer(to:) 的文档,你会在 Swift 标准库的文档下找到一个完整的Manual Memory Management category
    【解决方案2】:

    作为大卫suggested - 正确的决定。但是您可能会遇到错误。并且您所有的选项都将指向内存中的同一区域。这就是发生在我身上的事情:

    为避免这种情况,请像这样检查:

    func pointer(object: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer {
        return object
    }
    
    var optional1: Int?
    var optional2: Int?
    
    print( pointer(object: &optional1) ) // 0x0000000108f68090
    print( pointer(object: &optional2) ) // 0x0000000108f680a0
    

    【讨论】:

    • 永远不要在操场上检查内存。 Playgrounds 没有经过优化,工作方式与真正的 Swift 应用程序/框架项目完全不同,因此您应该始终使用实际的 Xcode 项目来调试内存问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2015-03-08
    • 1970-01-01
    • 2019-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多