【问题标题】:What's the difference between takeUnretainedValue and takeRetainedValue?takeUnretainedValue 和 takeRetainedValue 有什么区别?
【发布时间】:2026-02-11 21:05:01
【问题描述】:

takeUnretainedValuetakeRetainedValue 有什么区别?基于 Apple 的文档:

这两种方法都返回原始的未包装类型 目的。您根据您使用的 API 是否选择使用哪种方法 正在调用返回一个未保留或保留的对象。

但是我怎么知道非托管对象是非保留对象还是保留对象呢?例如,来自AddressBook 框架的方法ABAddressBookCreateWithOptions: 返回一个非托管对象ABAddressBook,一些教程将其视为保留对象。当使用ALAsset时,方法thumbnail返回一个非托管对象CGImage,一些教程认为这是一个非保留对象。

感谢您的帮助。

【问题讨论】:

    标签: swift memory-management unsafe-unretained retained-in-memory


    【解决方案1】:

    我如何知道非托管对象是非保留对象还是保留对象?

    这取决于您使用的 API。

    这里有一些约定:Ownership Polocy / Memory Management Programming Guide for Core Foundation

    基本上,如果函数名称包含单词“创建”或“复制”,请使用.takeRetainedValue()。如果函数名中包含“Get”一词,请使用.takeUnretainedValue()

    而且,如果它不包含任何一个,据我所知,我们仍然可以在几乎所有情况下使用.takeUnretainedValue()

    但是,每个规则都有例外 :) 例如,请参阅:
    Swift UnsafeMutablePointer<Unmanaged<CFString>?> allocation and print

    【讨论】:

    • 这是一个很好、简单且中肯的解释 :) 谢谢!所以,就我而言,因为ALAsset 方法someALAsset.defaultRepresentation().fullScreenImage() 返回一个非托管CGImage,那么我应该使用.takeUnretainedValue(),对吗?我的意思是,CGImage 在其构造函数中不包含“create”或“copy”。
    • 正确,fullScreenImage 不包含“创建”或“复制”。如果您不确定要使用哪个,您可能希望在 apple.com 中找到一些示例代码。例如,this sample 正在使用fullScreenImage,但没有使用CGImageRelease 发布结果。