Свифт, струны и адреса памяти
Есть кое-что, чего я не понимаю о том, как 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)
возвращает три разных адреса (но одинаковые адреса в скомпилированном проекте). То же самое наблюдение (для массивов и словарей) было сделано в Различном соединении между Массивом и Словарём.