Быстрые, строковые и запоминающие адреса
Есть что-то, что я не понимаю о том, как 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#//apple_ref/doc/uid/TP40014097-CH13-XID_134
Итак, почему у них есть два разных адреса памяти?
unsafeAddressOf(word0) // "UnsafePointer(0x7FCD1342ACE0)"
unsafeAddressOf(word1) // "UnsafePointer(0x7FCD13414260)"
3. Подробнее
Также обратите внимание, что String
является struct
, который как-то соответствует до AnyObject
.
Протестировано игровой площадкой Xcode 7 GM и Swift 2.0.
Ответы
Ответ 1
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)
возвращает три разных адреса (но те же адреса в скомпилированном
проект). Это же наблюдение (для массивов и словарей) было сделано
в Разный мост между Array и Dictionary.
Ответ 2
Swift 3.0
Unmanaged.passUnretained(объект).toOpaque()