我目前正在与copyCGImage方法(或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,数据提供程序仍然是相同的对象(和指针)。
还要注意,对于不可变对象,copy函数不必返回新对象。它可以只返回上一个对象(例如NSArray会发生这种情况)。
在randomdata的提供者中修改CGImage可能不是一件好事,因为您不知道数据的内部结构(它是JPEG数据源吗?是PNG数据源吗?是位图吗?)

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

10-13 04:57