【问题标题】:Swift, Strings and Memory AddressesSwift、字符串和内存地址
【发布时间】:2015-09-17 19:54:37
【问题描述】:

关于 Swift 如何管理 String(s) 的内存地址,我有些不明白

1。引用类型

这里fooboo 是两个指向相同内存位置的指针。

class Foo { }

let foo = Foo()
let boo = foo

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

很好。

2。值类型

let word0 = "hello"
let word1 = word0

现在word0word1value 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

那么为什么它们有 2 个不同的内存地址呢?

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

3。更多

还请注意,Stringstructsomehow conformsAnyObject

使用 Xcode 7 GM Playground 和 Swift 2.0 测试。

【问题讨论】:

  • "那么为什么它们有 2 个不同的内存地址?"那你为什么在乎呢?
  • String 在传递给期望 AnyObject 的函数时会自动桥接到 NSObject,另请参阅我对 stackoverflow.com/questions/32637688/… 的评论。实际上,我在编译的项目中得到了 word0/1 的相同输出,但在 Playground 中得到了不同的输出。
  • @matt Ahah...:D 是的。我开始想同样的事情。但是stackoverflow.com/questions/32626383/…这个问题和我回答下面cmets的激烈交流促使我问了这个问题。
  • 这里有类似的观察:stackoverflow.com/questions/31298461/…。我认为您不能对自动桥接到 Foundation 对象是否每次都返回相同的实例做出任何假设。
  • @MartinR:理解。十分感谢。如果你想写你的 cmets 作为答案,请考虑接受它。

标签: string swift memory-address value-type


【解决方案1】:
func unsafeAddressOf(object: AnyObject) -> UnsafePointer<Void>

采用AnyObject 参数,即的实例。 它返回指向用于引用对象的存储的指针 object.

addressOf() 不能与 struct 变量一起使用:

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)

返回三个不同的地址(但编译后的地址相同) 项目)。进行了相同的观察(对于数组和字典) 在A different bridging between Array and Dictionary

【讨论】:

  • 那么我们如何将它应用到结构中呢?如果我想要自定义结构的内存地址,TRUE 内存地址,零转换作为基础类对象,我该怎么办?
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    • 2023-03-21
    • 2023-03-07
    • 2017-05-03
    • 2017-01-18
    • 2015-07-10
    • 1970-01-01
    相关资源
    最近更新 更多