是否有任何方式来模拟[NSString stringWithFormat:@“%p”,myVar],从Objective-C,在新的Swift语言?
例如:
let str = "A String"
println(" str value \(str) has address: ?")
是否有任何方式来模拟[NSString stringWithFormat:@“%p”,myVar],从Objective-C,在新的Swift语言?
例如:
let str = "A String"
println(" str value \(str) has address: ?")
当前回答
斯威夫特5
extension String {
static func pointer(_ object: AnyObject?) -> String {
guard let object = object else { return "nil" }
let opaque: UnsafeMutableRawPointer = Unmanaged.passUnretained(object).toOpaque()
return String(describing: opaque)
}
}
用法:
print("FileManager.default: \(String.pointer(FileManager.default))")
// FileManager.default: 0x00007fff5c287698
print("nil: \(String.pointer(nil))")
// nil: nil
其他回答
这当然不是最快或最安全的方法。但这对我很管用。这将允许任何nsobject子类采用此属性。
public extension NSObject {
public var memoryAddress : String? {
let str = "\(self.self)".components(separatedBy: ": ")
guard str.count > 1 else { return nil }
return str[1].replacingOccurrences(of: ">", with: "")
}
}
//usage
let foo : String! = "hello"
Swift.print(foo.memoryAddress) // prints 0x100f12980
引用类型:
获取引用类型的内存地址是有意义的,因为它表示标识。 ===标识运算符用于检查两个对象是否指向同一个引用。 使用ObjectIdentifier获取内存地址
代码:
class C {}
let c1 = C()
let c2 = c1
//Option 1:
print("c1 address: \(Unmanaged.passUnretained(c1).toOpaque())")
//Option 2:
let o1 = ObjectIdentifier(c1)
let o2 = ObjectIdentifier(c2)
print("o1 -> c1 = \(o1)")
print("o2 -> c2 = \(o2)")
if o1 == o2 {
print("c1 = c2")
} else {
print("c1 != c2")
}
//Output:
//c1 address: 0x000060c000005b10
//o1 -> c1 = ObjectIdentifier(0x000060c000005b10)
//o2 -> c2 = ObjectIdentifier(0x000060c000005b10)
//c1 = c2
值类型:
获取值类型的内存地址的需求并不太重要(因为它是一个值),重点将更多地放在值的相等性上。
请注意,这个答案是相当古老的。书中描述的许多方法已经不再有效。特别是不能再访问.core。
但是@drew的回答是正确而简单的:
这现在是标准库的一部分:unsafeAddressOf。
所以你问题的答案是
println(" str value \(str) has address: \(unsafeAddressOf(str))")
以下是被标记为正确的原始答案(为了后代/礼貌):
Swift“隐藏”指针,但它们仍然存在于底层。(因为运行时需要它,并且出于与Objc和C的兼容性原因)
然而,有几件事要知道,但首先如何打印一个Swift字符串的内存地址?
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中,String是基本类型,而不是对象。 CInt是一个Swift类型映射到C int类型。 如果你想要一个对象的内存地址,你必须做一些不同的事情。 Swift有一些指针类型,可以在与C交互时使用,你可以在这里阅读:Swift指针类型 此外,你可以了解更多关于它们的声明(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 helper函数
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
其他答案都很好,尽管我正在寻找一种方法来获取整数形式的指针地址:
let ptr = unsafeAddressOf(obj)
let nullPtr = UnsafePointer<Void>(bitPattern: 0)
/// This gets the address of pointer
let address = nullPtr.distanceTo(ptr) // This is Int
只是跟进一下。
斯威夫特2
这现在是标准库的一部分:unsafeAddressOf。
/// Return an UnsafePointer to the storage used for `object`. There's
/// not much you can do with this other than use it to identify the
/// object
斯威夫特3
对于Swift 3,使用withUnsafePointer:
var str = "A String"
withUnsafePointer(to: &str) {
print(" str value \(str) has address: \($0)")
}