Как получить адрес памяти типа значения или пользовательской структуры в Swift?

Я пытаюсь получить более глубокое понимание того, как Свифт экземпляры типов значений:

поведение, которое вы видите в своем коде, всегда будет таким, как если бы копия место. Однако Swift выполняет только фактическую копию за кулисами когда это абсолютно необходимо.

чтобы продвинуть мое понимание, я хотел бы получить адрес памяти типа значения. Я попробовал unsafeAddressOf (), но это не работает со структурами и кажется, что стандартные типы библиотек Swift ссылаются на типы (например, строка приводится к NSString).

как я могу получить адрес памяти типа значения, например экземпляр Int или пользовательскую структуру в Swift?

3 ответов


согласно ответу Мартина R ' S

addressOf () нельзя использовать с переменными структуры. String-это структура, однако она автоматически соединяется с 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""

Swift 2.0:

Вы можете использовать этот unsafeAddressOf(someObject)

или в Swift 3.0:

использовать withUnsafePointer(to: someObejct) { print("\()") }


Я не уверен, что есть "рекомендуемый" способ сделать это, но один из методов-использовать withUnsafePointer(_:_:), например:

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

это напечатано 0x00007ffff52a011c8 на моей машине.