请注意,这个答案已经很老了。它描述的许多方法不再有效。特别是.core 不能再访问了。
不过@drew 的回答是正确而简单的:
现在这是标准库的一部分:unsafeAddressOf。
所以你的问题的答案是:
println(" str value \(str) has address: \(unsafeAddressOf(str))")
这是被标记为正确的原始答案(为了后代/礼貌):
Swift“隐藏”了指针,但它们仍然存在于底层。 (因为运行时需要它,并且出于与 Objc 和 C 的兼容性原因)
然而,有几件事要知道,但首先如何打印 Swift String 的内存地址?
var aString : String = "THIS IS A STRING"
NSLog("%p", aString.core._baseAddress) // _baseAddress is a COpaquePointer
// example printed address 0x100006db0
这会打印字符串的内存地址,如果你打开 XCode -> Debug Workflow -> View Memory 并转到打印的地址,你会看到字符串的原始数据。
由于这是一个字符串字面量,因此这是二进制存储中的内存地址(不是堆栈或堆)。
但是,如果你这样做了
var aString : String = "THIS IS A STRING" + "This is another String"
NSLog("%p", aString.core._baseAddress)
// example printed address 0x103f30020
这将在堆栈上,因为字符串是在运行时创建的
注意:.core._baseAddress 没有记录,我在变量检查器中发现它,它可能在未来被隐藏
_baseAddress 并非在所有类型上都可用,这里是另一个带有 CInt 的示例
var testNumber : CInt = 289
takesInt(&testNumber)
takesInt 是这样的 C 辅助函数
void takesInt(int *intptr)
{
printf("%p", intptr);
}
在 Swift 端,这个函数是takesInt(intptr: CMutablePointer<CInt>),所以它需要一个 CMutablePointer 到一个 CInt,你可以用 &varname 来获取它
函数打印0x7fff5fbfed98,在这个内存地址你会发现289(十六进制)。您可以使用*intptr = 123456更改其内容
现在,还有一些事情要知道。
字符串,在 swift 中,是一个原始类型,而不是一个对象。
CInt 是映射到 C int 类型的 Swift 类型。
如果你想要一个对象的内存地址,你必须做一些不同的事情。
Swift 有一些指针类型可以在与 C 交互时使用,你可以在这里阅读它们:Swift Pointer Types
此外,您可以了解更多关于他们探索他们的声明(cmd+点击类型),了解如何将指针类型转换为另一种类型
var aString : NSString = "This is a string" // create an NSString
var anUnmanaged = Unmanaged<NSString>.passUnretained(aString) // take an unmanaged pointer
var opaque : COpaquePointer = anUnmanaged.toOpaque() // convert it to a COpaquePointer
var mut : CMutablePointer = &opaque // this is a CMutablePointer<COpaquePointer>
printptr(mut) // pass the pointer to an helper function written in C
printptr 是我创建的一个 C 辅助函数,用这个实现
void printptr(void ** ptr)
{
printf("%p", *ptr);
}
再次,打印地址的示例:0x6000000530b0,如果您通过内存检查器,您将找到您的 NSString
在 Swift 中你可以用指针做一件事(这甚至可以用 inout 参数来做)
func playWithPointer (stringa :AutoreleasingUnsafePointer<NSString>)
{
stringa.memory = "String Updated";
}
var testString : NSString = "test string"
println(testString)
playWithPointer(&testString)
println(testString)
或者,与 Objc / c 交互
// objc side
+ (void)writeString:(void **)var
{
NSMutableString *aString = [[NSMutableString alloc] initWithFormat:@"pippo %@", @"pluto"];
*var = (void *)CFBridgingRetain(aString); // Retain!
}
// swift side
var opaque = COpaquePointer.null() // create a new opaque pointer pointing to null
TestClass.writeString(&opaque)
var string = Unmanaged<NSString>.fromOpaque(opaque).takeRetainedValue()
println(string)
// this prints pippo pluto