UnsafeRawPointer assumeMemoryBound vs. bindMemory

时间:2017-12-22 10:44:23

标签: swift pointers memory

任何人都可以解释text: View Contact Details rel: ['', 'Principal', 'Name', '-', 'POONAM', 'POONI', 'Mobile', 'No.', '-', '8568940353', 'Email', 'ID', '-', 'GAURAVGUPTA806@YAHOO.COM', ''] rel: Principal Name - POONAM POONI Mobile No. - 8568940353 Email ID - GAURAVGUPTA806@YAHOO.COM ----- text: View Contact Details rel: ['', 'Principal', 'Name', '-', 'POONAM', 'POONI', 'Mobile', 'No.', '-', '8568940353', 'Email', 'ID', '-', 'GAURAVGUPTA806@YAHOO.COM', ''] rel: Principal Name - POONAM POONI Mobile No. - 8568940353 Email ID - GAURAVGUPTA806@YAHOO.COM ----- text: View Contact Details rel: ['', 'Principal', 'Name', '-', 'POONAM', 'POONI', 'Mobile', 'No.', '-', '8568940353', 'Email', 'ID', '-', 'GAURAVGUPTA806@YAHOO.COM', ''] rel: Principal Name - POONAM POONI Mobile No. - 8568940353 Email ID - GAURAVGUPTA806@YAHOO.COM ----- text: View Contact Details rel: ['', 'Principal', 'Name', '-', 'POONAM', 'POONI', 'Mobile', 'No.', '-', '8568940353', 'Email', 'ID', '-', 'GAURAVGUPTA806@YAHOO.COM', ''] rel: Principal Name - POONAM POONI Mobile No. - 8568940353 Email ID - GAURAVGUPTA806@YAHOO.COM ----- text: View Contact Details rel: ['', 'Principal', 'Name', '-', 'POONAM', 'POONI', 'Mobile', 'No.', '-', '8568940353', 'Email', 'ID', '-', 'GAURAVGUPTA806@YAHOO.COM', ''] rel: Principal Name - POONAM POONI Mobile No. - 8568940353 Email ID - GAURAVGUPTA806@YAHOO.COM ----- text: View Contact Details rel: ['', 'Principal', 'Name', '-', 'POONAM', 'POONI', 'Mobile', 'No.', '-', '8568940353', 'Email', 'ID', '-', 'GAURAVGUPTA806@YAHOO.COM', ''] rel: Principal Name - POONAM POONI Mobile No. - 8568940353 Email ID - GAURAVGUPTA806@YAHOO.COM ----- text: View Contact Details rel: ['', 'Principal', 'Name', '-', 'POONAM', 'POONI', 'Mobile', 'No.', '-', '8568940353', 'Email', 'ID', '-', 'GAURAVGUPTA806@YAHOO.COM', ''] rel: Principal Name - POONAM POONI Mobile No. - 8568940353 Email ID - GAURAVGUPTA806@YAHOO.COM ----- text: View Contact Details rel: ['', 'Principal', 'Name', '-', 'POONAM', 'POONI', 'Mobile', 'No.', '-', '8568940353', 'Email', 'ID', '-', 'GAURAVGUPTA806@YAHOO.COM', ''] rel: Principal Name - POONAM POONI Mobile No. - 8568940353 Email ID - GAURAVGUPTA806@YAHOO.COM ----- text: View Contact Details rel: ['', 'Principal', 'Name', '-', 'POONAM', 'POONI', 'Mobile', 'No.', '-', '8568940353', 'Email', 'ID', '-', 'GAURAVGUPTA806@YAHOO.COM', ''] rel: Principal Name - POONAM POONI Mobile No. - 8568940353 Email ID - GAURAVGUPTA806@YAHOO.COM ----- text: View Contact Details rel: ['', 'Principal', 'Name', '-', 'POONAM', 'POONI', 'Mobile', 'No.', '-', '8568940353', 'Email', 'ID', '-', 'GAURAVGUPTA806@YAHOO.COM', ''] rel: Principal Name - POONAM POONI Mobile No. - 8568940353 Email ID - GAURAVGUPTA806@YAHOO.COM ----- UnsafeRawPointer.assumimgMemoryBound(to:)之间的区别吗?

编译或运行时差的一个实际例子将更受欢迎。

Swift DocUnsafeRawPointer.bindMemory(to:capacity:)

  

此API允许内存区域在程序的不同位置保存不相关的类型。将未初始化的内存绑定到类型会使内存准备存储该类型的值。已初始化的绑定内存将内存中的值重新解释为新类型。如果旧值非常重要(需要销毁)或者在覆盖之前从内存中读取它们,则新类型必须与旧类型相互布局兼容。

是什么意思将未初始化的内存绑定到某个类型会准备内存来存储该类型的值?它分配了字节,对吧?那么bindMemory(to:capacity:)完成后有什么不同?

1 个答案:

答案 0 :(得分:10)

Swift中的分配内存可以是:

  • 未初始化的原始内存
  • 绑定到类型的未初始化内存
  • 初始化内存绑定到类型

使用UnsafeMutableRawPointer.allocate(bytes:alignedTo:)分配内存时,会获得未初始化的原始内存。

使用UnsafeMutablePointer<T>.allocate(capacity:)分配内存时,会获得绑定到T类型的未初始化内存。

  • bindMemory(to:capacity:)(重新)将指针的内存绑定到一个新类型,并返回一个类型指针来访问它。它可以在任何上述状态的指向内存的指针上调用;但是,如果内存已初始化,则新绑定类型必须与旧绑定类型布局兼容,并且两种类型都应为trivial

    请注意,此方法执行分配或初始化;它只是改变了内存的绑定类型。

  • assumingMemoryBound(to:)是一种从原始指针获取类型指针的方法,该指针已经知道指向绑定到给定类型的内存。如果内存未绑定到此类型,则通过您返回的类型指针访问内存是未定义的行为

这里需要注意的一件重要事情是,内存只能在给定时间绑定到一种类型。您可以自由重新绑定到其他类型(具有上述初始化内存的限制);但是,尝试访问绑定到给定类型的内存作为无关的类型会违反严格别名,因此未定义的行为

需要注意的另一件事是相关类型和布局兼容类型是独立的概念:

  • 如果绑定到类型T的内存可以按位重新解释为类型{{},则类型U布局兼容且类型为U 1}}。请注意,这不一定是双向关系。例如,如果T的一个“实例”可以重新解释为2 x Int,则(Int, Int)(Int, Int)的布局兼容。反过来不可能是真的;您无法从单个Int形成(Int, Int)值。

  • 如果您可以将重叠内存与这些类型别名,则相关有两种类型。例如,如果您有IntUnsafePointer<T>,如果UnsafePointer<U>T是不相关的类型,那么它们就无法指向彼此重叠的内存。

但是,我不相信Swift已经正式定义了这些术语的任何规则(我希望这将伴随ABI稳定性)。

  

那么U完成后有什么不同?

目前,什么都没有。正如邮件列表讨论中的Andrew Trick says Martin linked to

  

绑定内存与编译器通信,内存位置对于类型化访问是安全的。在运行时没有任何事情发生 - 直到有人写了类型安全消毒剂。它影响内存位置的抽象状态,与用于访问该内存的指针变量无关。绑定内存返回一个类型指针,以方便和清晰,但没有什么特别的指针值。

有关此主题的进一步阅读,请参阅memory model explanation section of SE-0107以及此unofficial guide to strict aliasing in Swift