swift2 如何在Swift中获取值类型或自定义结构体的内存地址?

izkcnapc  于 2022-11-06  发布在  Swift
关注(0)|答案(3)|浏览(218)

我试图更深入地了解Swift如何复制值类型:
你在代码中看到的行为总是像发生了复制一样。然而,Swift只在绝对必要的时候才在后台执行实际的复制。
为了加深我的理解,我想获取一个值类型的内存地址。我尝试了unsafeAddressOf(),但是this doesn't work with structs and it seems to cast Swift's standard library types to reference types(例如,String被转换为NSString)。

如何获取值类型的内存地址,如Int的示例或Swift中的自定义结构?

bprjcwpo

bprjcwpo1#

根据马丁R的回答
addressOf()不能与结构变量一起使用。字符串是一个结构,但是,当传递给需要对象的函数时,它会自动桥接到NSString。
根据nschum的回答,你可以得到一个struct、内置类型或对象引用的(堆栈)地址,如下所示:

import UIKit

func address(o: UnsafePointer<Void>) -> Int {
    return unsafeBitCast(o, Int.self)
}

func addressHeap<T: AnyObject>(o: T) -> Int {
    return unsafeBitCast(o, Int.self)
}

struct myStruct {
    var a: Int
}

class myClas {

}
//struct
var struct1 = myStruct(a: 5)
var struct2 = struct1
print(NSString(format: "%p", address(&struct1))) // -> "0x10f1fd430\n"
print(NSString(format: "%p", address(&struct2))) // -> "0x10f1fd438\n"

//String
var s = "A String"
var aa = s
print(NSString(format: "%p", address(&s))) // -> "0x10f43a430\n"
print(NSString(format: "%p", address(&aa))) // -> "0x10f43a448\n"

//Class
var class1 = myClas()
var class2 = class1
print(NSString(format: "%p", addressHeap(class1))) // -> 0x7fd5c8700970
print(NSString(format: "%p", addressHeap(class2))) // -> 0x7fd5c8700970

unsafeAddressOf(class1) //"UnsafePointer(0x7FD95AE272E0)"
unsafeAddressOf(class2) //"UnsafePointer(0x7FD95AE272E0)"

//Int
var num1 = 55
var num2 = num1
print(NSString(format: "%p", address(&num1))) // -> "0x10f1fd480\n"
print(NSString(format: "%p", address(&num2))) // -> "0x10f1fd488\n"

我发现的一件事是,如果myStruct没有值,地址将被保留不变:

struct myStruct {

}

var struct1 = myStruct()
var struct2 = struct1
print(NSString(format: "%p", address(&struct1))) // -> ""0xa000000000070252\n""
print(NSString(format: "%p", address(&struct2))) // -> ""0xa000000000070252\n""
xeufq47z

xeufq47z2#

斯威夫特2.0:
您可以使用此unsafeAddressOf(someObject)
或在Swift 3.0中:
使用withUnsafePointer(to: someObejct) { print("\($0)") }

3df52oht

3df52oht3#

我不确定是否有“推荐”的方法来实现这一点,但有一种方法是使用withUnsafePointer(_:_:),如下所示:

var s: String = "foo"
withUnsafePointer(&s) { NSLog("\($0)") }

这在我的机器上打印了0x00007ffff52a011c8

相关问题