Swift, cadenas y direcciones de memoria

Hay algo que no entiendo acerca de cómo Swift maneja la dirección de memoria de String(s)

1. Tipos de referencia

Aquí foo y boo son 2 punteros a la misma ubicación de memoria .

 class Foo { } let foo = Foo() let boo = foo unsafeAddressOf(foo) // "UnsafePointer(0x7FCD13719BE0)" unsafeAddressOf(boo) // "UnsafePointer(0x7FCD13719BE0)" 

Bueno.

2. Tipos de valores

 let word0 = "hello" let word1 = word0 

Ahora word0 y word1 son value types pero aquí está involucrado el mecanismo de copy on write .

[…] Sin embargo, Swift solo realiza una copia real detrás de las escenas cuando es absolutamente necesario hacerlo. Swift gestiona todas las copias de valor para garantizar un rendimiento óptimo, y no debe evitar la asignación para tratar de adelantarse a esta optimización. https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html#//apple_ref/doc/uid/TP40014097-CH13-XID_134

Entonces, ¿por qué tienen 2 direcciones de memoria diferentes?

 unsafeAddressOf(word0) // "UnsafePointer(0x7FCD1342ACE0)" unsafeAddressOf(word1) // "UnsafePointer(0x7FCD13414260)" 

3 más

También tenga en cuenta que String es una struct que de alguna manera se ajusta a AnyObject .

Probado con Xcode 7 GM Playground y Swift 2.0.

 func unsafeAddressOf(object: AnyObject) -> UnsafePointer 

toma un parámetro AnyObject , es decir, una instancia de una clase . Devuelve el puntero al almacenamiento utilizado para el objeto al que hace referencia el object .

addressOf() no se puede usar con variables struct :

 struct Foo { } var f = Foo() let a = unsafeAddressOf(f) // error: cannot invoke 'unsafeAddressOf' with an argument list of type '(Foo)' 

String es una struct , sin embargo , se puentea automáticamente a NSString cuando se pasa a una función que espera un objeto. Asi que

 let word0 = "hello" let p1 = unsafeAddressOf(word0) 

en realidad se ejecuta

 let p1 = unsafeAddressOf(word0 as NSString) 

No obtiene la dirección de la variable word0 , sino el puntero a la ubicación de la memoria del objeto NSString puenteado.

Parece que no se puede hacer ninguna suposición sobre si este puente devuelve el objeto NSString idéntico (o más generalmente, el mismo objeto Foundation) cuando se realiza repetidamente en la misma cadena Swift. En un patio de recreo, incluso

 let word0 = "hello" let p1 = unsafeAddressOf(word0) let p2 = unsafeAddressOf(word0) let p3 = unsafeAddressOf(word0) 

devuelve tres direcciones diferentes (pero las mismas direcciones en un proyecto comstackdo). La misma observación (para matrices y diccionarios) se realizó en Un puente diferente entre Array y Dictionary .

Swift 3.0 Unmanaged.passUnretained (object) .toOpaque ()