ios - 为什么 CGImage 的 copy() 方法会在相同的内存地址上生成图像?

标签 ios swift pointers

我目前正在为 CGImagecopy 方法(或者 CGImage 的一般工作方式?)苦苦挣扎。

背景:我用 UnsafeMutablePointer 操作了一张图片,结果出现了 EXC_BAD_ACCESS 错误。我发现,这是由 CGImage 已经显示在 UIView 中(封装在 UIImage 中)引起的。所以我创建了 CGImage 的副本并且它可以工作。由此我得出结论,copy 必须创建图像的真实副本。

但是:在用下面的代码检查指针时,我注意到两个指针指向的地址是相同的。

这怎么可能?

import UIKit

var uiImageIn = UIImage(named: "image2.png")!

var image1 = uiImageIn.cgImage!
var image2 = image1.copy()!

var ptr1 = UnsafeMutablePointer<UInt8>.init(mutating: CFDataGetBytePtr(image1.dataProvider!.data)!)
var ptr2 = UnsafeMutablePointer<UInt8>.init(mutating: CFDataGetBytePtr(image2.dataProvider!.data)!)

print("Image1Ptr: \(ptr1)")
print("Image2Ptr: \(ptr2) --> Same result as for ptr1!?")

我希望 ptr1 和 ptr2 在这里有所不同。

更新

好的,找出我的错误: 根本没有必要创建 CGImage 的副本,因为访问 dataProvider 已经创建了位图数据的副本。但是:在我上面的代码中,我没有将 dataProvider 分配给任何变量。因此,它会立即被释放,并且大部分时间都会重复使用该地址(此外,如果我通过其中一个指针访问数据,因为 dataProvider 已经被释放,它会导致错误)。

在下面的例子中,指针的地址是不同的: 导入 UIKit

var uiImageIn = UIImage(named: "image.png")!

var image1 = uiImageIn.cgImage!

var data1 = image1.dataProvider!.data
var data2 = image1.dataProvider!.data

var ptr1 = UnsafeMutablePointer<UInt8>.init(mutating: CFDataGetBytePtr(data1)!)
var ptr2 = UnsafeMutablePointer<UInt8>.init(mutating: CFDataGetBytePtr(data2)!)

print("Image1Ptr: \(ptr1)")
print("Image2Ptr: \(ptr2)")

最佳答案

你的期望是错误的。 copy() 创建浅拷贝。这意味着创建了一个新对象,但所有内部结构仅通过引用进行复制。这意味着即使您收到一个新的 CGImage,数据提供者仍将是相同的对象(和指针)。

另请注意,对于不可变对象(immutable对象),copy 函数不必返回新对象。它可以只返回前一个对象(例如 NSArray 会发生什么)。

在随机 CGImage 的提供者内部修改 data 可能不是一件好事,因为你不知道数据的内部结构(是 JPEG数据源?是PNG数据源?是位图?)

关于ios - 为什么 CGImage 的 copy() 方法会在相同的内存地址上生成图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53932107/

相关文章:

swift - $T4 没有名为 Generator ERROR swift 的成员

C++:为什么 const_cast 是邪恶的?

ios - 错误 : Like/Unlike and Comment using LinkedIn REST Api for iOS

ios - ld : framework not found FirebaseAnalytics after upgrading from 4. x.x 到 5.x.x firebase 通过 cocoapods

ios - Swift 中的惰性属性等同于 Objective C 中的惰性 Init getter

ios - Flurry 崩溃报告不起作用

c - 打印行为

连接字符串 (2)

Card.io 扫描信用卡后,iOS Phonegap 应用程序崩溃

ios - 类型 'GameScene' 的值在 Swift 中没有成员 'presentViewController'