Es fundamental entender el código de forma correcta previamente a utilizarlo a tu trabajo y si ttienes algo que aportar puedes compartirlo con nosotros.
Solución:
Nota: Esto es para tipos de referencia.
Rápido 4/5:
print(Unmanaged.passUnretained(someVar).toOpaque())
Imprime la dirección de memoria de someVar. (gracias a @Ying)
Rápido 3.1:
print(Unmanaged.passUnretained(someVar as AnyObject).toOpaque())
Imprime la dirección de memoria de someVar.
rápido 2
Esto ahora es parte de la biblioteca estándar: 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
rápido 3
Para Swift 3, use withUnsafePointer
:
var str = "A String"
withUnsafePointer(to: &str)
print(" str value (str) has address: ($0)")
Tenga en cuenta que esta respuesta era bastante antigua. Muchos de los métodos que describe ya no funcionan. Específicamente .core
ya no se puede acceder.
Sin embargo, la respuesta de @drew es correcta y simple:
Esto ahora es parte de la biblioteca estándar: unsafeAddressOf.
Así que la respuesta a tus preguntas es:
println(" str value (str) has address: (unsafeAddressOf(str))")
Aquí está la respuesta original que se marcó como correcta (para posteridad/cortesía):
Swift “oculta” los punteros, pero aún existen bajo el capó. (porque el tiempo de ejecución lo necesita y por razones de compatibilidad con Objc y C)
Sin embargo, hay algunas cosas que debe saber, pero primero, ¿cómo imprimir la dirección de memoria de una cadena Swift?
var aString : String = "THIS IS A STRING"
NSLog("%p", aString.core._baseAddress) // _baseAddress is a COpaquePointer
// example printed address 0x100006db0
Esto imprime la dirección de memoria del stringsi abre XCode -> Flujo de trabajo de depuración -> Ver memoria y va a la dirección impresa, verá los datos sin procesar del string. Dado que este es un string literal, esta es una dirección de memoria dentro del almacenamiento del binario (no pila o montón).
Sin embargo, si lo haces
var aString : String = "THIS IS A STRING" + "This is another String"
NSLog("%p", aString.core._baseAddress)
// example printed address 0x103f30020
Esto estará en la pila, porque el string se crea en tiempo de ejecución
NOTA: .core._baseAddress no está documentado, lo encontré buscando en el inspector de variables y puede estar oculto en el futuro
_baseAddress no está disponible en todos los tipos, aquí otro ejemplo con un CInt
var testNumber : CInt = 289
takesInt(&testNumber)
Donde takesInt
es una función auxiliar de C como esta
void takesInt(int *intptr)
printf("%p", intptr);
En el lado de Swift, esta función es takesInt(intptr: CMutablePointer
por lo que lleva un CMutablePointer a un CInt, y puede obtenerlo con &varname
La función imprime 0x7fff5fbfed98
, y en esta dirección de memoria encontrarás 289 (en notación hexadecimal). Puede cambiar su contenido con *intptr = 123456
Ahora, algunas otras cosas que debe saber.
String, en swift, es un tipo primitivo, no un objeto.
CInt es un tipo Swift asignado al tipo C int.
Si desea la dirección de memoria de un objeto, debe hacer algo diferente.
Swift tiene algunos tipos de punteros que se pueden usar al interactuar con C, y puede leer sobre ellos aquí: Tipos de punteros de Swift
Además, puede comprender más sobre ellos explorando su declaración (cmd + clic en el tipo), para comprender cómo convertir un tipo de puntero en otro
var aString : NSString = "This is a string" // create an NSString
var anUnmanaged = Unmanaged.passUnretained(aString) // take an unmanaged pointer
var opaque : COpaquePointer = anUnmanaged.toOpaque() // convert it to a COpaquePointer
var mut : CMutablePointer = &opaque // this is a CMutablePointer
printptr(mut) // pass the pointer to an helper function written in C
printptr
es una función auxiliar de C que creé, con esta implementación
void printptr(void ** ptr)
printf("%p", *ptr);
Nuevamente, un ejemplo de la dirección impresa: 0x6000000530b0
y si pasa por el inspector de memoria encontrará su NSString
Una cosa que puede hacer con punteros en Swift (esto incluso se puede hacer con parámetros de entrada y salida)
func playWithPointer (stringa :AutoreleasingUnsafePointer)
stringa.memory = "String Updated";
var testString : NSString = "test string"
println(testString)
playWithPointer(&testString)
println(testString)
O, interactuando con 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.fromOpaque(opaque).takeRetainedValue()
println(string)
// this prints pippo pluto
Nos encantaría que puedieras mostrar este post si lograste el éxito.