是否有任何方式来模拟[NSString stringWithFormat:@“%p”,myVar],从Objective-C,在新的Swift语言?

例如:

let str = "A String"
println(" str value \(str) has address: ?")

当前回答

这是为了Swift 3。

像@CharlieMonroe一样,我想以整数形式获取地址。具体来说,我想要Thread对象的地址作为诊断日志记录模块中的线程ID,用于没有线程名可用的情况。

根据查理·门罗的代码,这是我目前想出的。但注意,我对霉霉很陌生,这可能不正确……

  // Convert the memory address of the current Thread object into an Int for use as a thread ID
  let objPtr = Unmanaged.passUnretained(Thread.current).toOpaque()
  let onePtr = UnsafeMutableRawPointer(bitPattern: 1)!  // 1 used instead of 0 to avoid crash
  let rawAddress : Int64 = onePtr.distance(to: objPtr) + 1  // This may include some high-order bits
  let address = rawAddress % (256 * 1024 * 1024 * 1024)  // Remove high-order bits

最后一条语句存在,因为如果没有它,我将获得像0x60000007DB3F这样的地址。最后一条语句中的模运算将其转换为0x7DB3F。

其他回答

斯威夫特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

引用类型:

获取引用类型的内存地址是有意义的,因为它表示标识。 ===标识运算符用于检查两个对象是否指向同一个引用。 使用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

值类型:

获取值类型的内存地址的需求并不太重要(因为它是一个值),重点将更多地放在值的相等性上。

其他答案都很好,尽管我正在寻找一种方法来获取整数形式的指针地址:

let ptr = unsafeAddressOf(obj)
let nullPtr = UnsafePointer<Void>(bitPattern: 0)

/// This gets the address of pointer
let address = nullPtr.distanceTo(ptr) // This is Int

只是跟进一下。

在Swift4 about Array中:

    let array1 = [1,2,3]
    let array2 = array1
    array1.withUnsafeBufferPointer { (point) in
        print(point) // UnsafeBufferPointer(start: 0x00006000004681e0, count: 3)
    }
    array2.withUnsafeBufferPointer { (point) in
        print(point) // UnsafeBufferPointer(start: 0x00006000004681e0, count: 3)
    }

@Drew提供的答案只能用于类类型。 @nschum提供的答案只能用于结构类型。

但是,如果使用第二种方法获取值类型为element的数组的地址。Swift会复制整个数组,因为在Swift数组是写时复制,Swift不能确保它的行为一旦它把控制权传递给C/ c++(这是通过使用&来获取地址触发)。如果你用第一个方法,它会自动把数组转换成NSArray这当然是我们不想要的。

所以我发现最简单和统一的方法是使用lldb指令帧变量-L yourVariableName。

或者你可以把他们的答案结合起来:

func address(o: UnsafePointer<Void>) {
    let addr = unsafeBitCast(o, Int.self)
    print(NSString(format: "%p", addr))
}

func address<T: AnyObject>(o: T) -> String{
    let addr = unsafeBitCast(o, Int.self)
    return NSString(format: "%p", addr) as String
}