Swift中调用CFRelease报错不可用,是否仅适用于OC、官方文档有误?
问题背景
根据苹果官方文档说明,CGImageSourceCreateWithData(_:_:) 方法返回的图像源对象,文档标注开发者需要调用CFRelease手动释放。
按照文档说明编写图片降采样逻辑时,手动加入CFRelease调用的代码如下:
func downsampling(imageName: String, to pointSize: CGSize, scale: CGFloat = UIScreen.main.scale) -> UIImage? { let imageData = NSDataAsset(name: imageName)?.data let imageSourceOptions = [kCGImageSourceShouldCache: false] guard let imageSource = CGImageSourceCreateWithData(imageData! as CFData, imageSourceOptions as CFDictionary) else { return nil } let maxDimensionInPixels = min(pointSize.width, pointSize.height/4) * scale let downsamplingOptions = [ kCGImageSourceCreateThumbnailFromImageAlways: true, kCGImageSourceShouldCacheImmediately: true, kCGImageSourceCreateThumbnailWithTransform: true, kCGImageSourceThumbnailMaxPixelSize: maxDimensionInPixels ] as CFDictionary guard let downsampledImage = CGImageSourceCreateImageAtIndex(imageSource, 0, downsamplingOptions) else { return nil } CFRelease(imageSource) return UIImage(cgImage: downsampledImage) }
编译时直接抛出错误:
'CFRelease' is unavailable: Core Foundation objects are automatically memory managed
待确认的问题如下:
CFRelease是否仅适用于Objective-C?- Swift中Core Foundation对象是否已经实现自动内存管理,无需手动释放?
- 苹果官方文档针对Swift场景的相关说明是否存在笔误?
解答
三个问题的结论很明确:
CFRelease不是Objective-C专属API,但在Swift的默认编译环境下被禁止手动调用。Swift从最初版本就完成了Core Foundation对象的ARC适配,所有编译器可识别内存管理语义的Core Foundation对象,都会自动纳入引用计数管理,编译器会自动在合适的位置插入CFRetain/CFRelease调用,手动调用CFRelease会导致重复释放,因此编译器直接把这个API标记为不可用。只有极少数涉及未标注内存语义的CF类型、自定义CF桥接的底层场景,才需要用到手动内存管理API,常规业务开发碰不到这类情况。- 你代码中创建的
CGImageSource实例不需要手动释放,直接删除CFRelease(imageSource)这行代码即可。当imageSource变量超出作用域、没有其他强引用时,ARC会自动释放对应对象,不会产生内存泄漏。 - 苹果文档没有笔误,只是Core Foundation相关文档的内存管理说明默认基于Objective-C语境编写。这套文档的核心内容成型远早于Swift发布,内存管理规则的描述针对的是手动引用计数(MRC)下的Objective-C开发场景——在Objective-C MRC环境下,按照Core Foundation的Create规则,名称带Create/Copy的API返回的对象确实需要调用者手动释放;但在Swift环境下,编译器会自动识别这类Create/Copy语义的返回值,自动处理引用计数,完全不需要照搬MRC时代的手动释放写法。
额外提醒:代码中
imageData!的强制解包存在运行时崩溃风险,当对应名称的图片资源不存在时会直接触发崩溃,建议替换为可选绑定做安全处理。
内容的提问来源于stack exchange,提问作者test1229
相关产品推荐
相关产品推荐

