我目前正在与copy
的CGImage
方法(或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/