From: Stackoverflow Question
Swift “hides” pointers, but they still exists under the hood. (because the runtime needs it, and for compatibility reasons with Objc and C)
There are few things to know however, but first how to print the memory address of a Swift String?
var aString : String = "THIS IS A STRING" NSLog("%p", aString.core._baseAddress) // _baseAddress is a COpaquePointer // example printed address 0x100006db0
This prints the memory address of the string, if you open XCode -> Debug Workflow -> View Memory and go to the printed address, you will see the raw data of the string. Since this is a string literal, this is a memory address inside the storage of the binary (not stack or heap).
However, if you do
var aString : String = "THIS IS A STRING" + "This is another String" NSLog("%p", aString.core._baseAddress) // example printed address 0x103f30020
This will be on the stack, because the string is created at runtime
NOTE: .core._baseAddress is not documented, I found it looking in the variable inspector, and it may be hidden in the future
_baseAddress is not available on all types, here another example with a CInt
var testNumber : CInt = 289 takesInt(&testNumber)
Where takesInt is a C helper function like this
void takesInt(int *intptr) { printf("%p", intptr); }
On the Swift side, this function is takesInt(intptr: CMutablePointer), so it takes a CMutablePointer to a CInt, and you can obtain it with &varname
The function prints 0x7fff5fbfed98, an at this memory address you will find 289 (in hexadecimal notation). You can change its content with *intptr = 123456
Now, some other things to know.
String, in swift, is a primitive type, not an object.
CInt is a Swift type mapped to the C int Type.
If you want the memory address of an object, you have to do something different.
Swift has some Pointer Types that can be used when interacting with C, and you can read about them here: Swift Pointer Types
Moreover, you can understand more about them exploring their declaration (cmd+click on the type), to understand how to convert a type of pointer into another
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 is a C helper function I created, with this implementation
void printptr(void ** ptr) { printf("%p", *ptr); }
Again, an example of the address printed: 0x6000000530b0 , and if you go through memory inspector you will find your NSString
One thing you can do with pointers in Swift (this can even be done with inout parameters)
func playWithPointer (stringa :AutoreleasingUnsafePointer) { stringa.memory = "String Updated"; } var testString : NSString = "test string" println(testString) playWithPointer(&testString) println(testString)
Or, interacting with 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