Свифт, струны и адреса памяти

Есть кое-что, чего я не понимаю о том, как Swift управляет адресом памяти String(s)

1. Типы ссылок

Вот foo а также boo 2 указателя на одну и ту же ячейку памяти.

class Foo { }

let foo = Foo()
let boo = foo

unsafeAddressOf(foo) // "UnsafePointer(0x7FCD13719BE0)"
unsafeAddressOf(boo) // "UnsafePointer(0x7FCD13719BE0)" 

Хорошо.

2. Типы значений

let word0 = "hello"
let word1 = word0

Сейчас word0 а также word1 являются value types но здесь copy on write механизм задействован.

[...] Тем не менее, Swift выполняет фактическое копирование за кулисами только тогда, когда это абсолютно необходимо. Swift управляет всем копированием значений, чтобы обеспечить оптимальную производительность, и вам не следует избегать присвоения, чтобы попытаться опередить эту оптимизацию. https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html

Так почему у них 2 разных адреса памяти?

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

3. Больше

Также обратите внимание, что String это struct что- то соответствует AnyObject,

Протестировано с игровой площадкой Xcode 7 GM и Swift 2.0.

2 ответа

Решение
func unsafeAddressOf(object: AnyObject) -> UnsafePointer<Void>

занимает AnyObject параметр, то есть экземпляр класса. Возвращает указатель на хранилище, используемое для объекта, на который ссылается object,

addressOf() не может использоваться с переменными структуры:

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

String это structоднако он автоматически соединяется с NSString когда передается функции, ожидающей объект. Так

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

на самом деле выполняет

let p1 = unsafeAddressOf(word0 as NSString)

Вы получаете не адрес word0 переменная, но указатель на ячейку памяти моста NSString объект.

Кажется, что вы не можете делать какие-либо предположения о том, возвращает ли этот мост идентичный NSString объект (или, в более общем смысле, один и тот же объект Foundation), когда выполняется несколько раз для одной и той же строки Swift На детской площадке даже

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

возвращает три разных адреса (но одинаковые адреса в скомпилированном проекте). То же самое наблюдение (для массивов и словарей) было сделано в Различном соединении между Массивом и Словарём.

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

Другие вопросы по тегам