我试图让图片与视图相关联,但Xcode会给我一个错误。这是代码:
@IBOutlet var imageView: IKImageView // Link to the image view.
func saveImage() {
var newImage: CGImageRef = imageView.image() // Line with an error.
}
我有一个awakeFromNib
函数可以在视图中设置图像。上面的代码会返回'Unmanaged<CGImage>' is not convertible to 'CGImageRef'
。
我知道Swift中的类型是可选的,但我不明白为什么会出现此错误,IKImageView Class Reference明确表示让IKImageView的图像返回CGImageRef。
答案 0 :(得分:6)
这与将Objective C API桥接到Swift有关。通过将原始Objective C标头转换为Swift版本,已经桥接了Swift版本的API(我认为主要是自动的)。在许多情况下,转换可以计算出您将要回归的价值,因此在Swift中您可以得到正常的&#34;您可以按照预期使用的类型。
但是,转换仍在进行中。在这种情况下,您所看到的是一种类型,用于帮助您在转换过程无法知道您是否会取回已保留的对象时手动管理内存对于你或不是,因为API没有它可以用来解决它的传统注释。
Unmanaged
类型有效地说&#34;您必须告诉我如何处理所包含的值以使内存管理正确&#34;。一旦获得非托管值,就应该调用其中两种方法之一:
takeUnretainedValue()
takeRetainedValue()
...取决于你回来的对象是&#34; + 0&#34;或&#34; + 1&#34;。所以,你应该做的事情如下:
var newImage: CGImage = imageView.image().takeUnretainedValue()
一旦你完成了(你应该立即做了),你已经给Swift足够的暗示它现在可以用ARC正确地管理对象了,并得到了自己正确类型的有效参考。
在Swift Interoperability in Depth&#34;结束时简要介绍了这个问题。今年的WWDC视频。
答案 1 :(得分:1)
查看the new version of the IKImageView
reference that shows Swift declarations中的image()
方法,您会看到它返回Unmanaged<CGImage>!
。这意味着没有设置ImageKit,以便编译器可以在其API上自动推断CoreFoundation内存管理语义。 (这会影响Swift翻译和ObjC隐式ARC桥接。)它应该是,所以'{是a good bug to file。
当编译器无法自动推断其ARC行为时,Swift类型Unmanaged<T>
是您与CF类型交互的方式。要获得基础类型,请调用takeUnretainedValue()
或takeRetainedValue()
- 您必须根据您调用的API是否已经保留其返回的值来选择哪个。令人兴奋的猜测! (同样,消除猜测会a good bug to file。)您可以在Using Swift with Cocoa and Objective-C中详细了解这一点。
无论如何,在这种情况下,您可能希望IKImageView
在提供CGImage
时不会增加Unmanaged
的保留计数,因此您可以像这样展开var newImage: CGImage = imageView.image().takeUnretainedValue()
:
Ref
另请注意,在Swift中使用CF类型时,不需要CGImageRef
后缀。 (CGImage
是{{1}}的类型。)Swift允许您使用CF类型,就好像它们是Swift对象(而不是作为不透明C类型的C指针)。