在UIImageWriteToSavedPhotosAlbum中使用contextInfo,UnsafeRawPointer - Swift 3

时间:2016-12-12 03:19:19

标签: ios swift

我有UITableView。点按某个单元格后,我的应用会生成相关图片。图像生成在后台线程上完成,因为一些图像会花费相当长的时间来渲染。渲染图像后,在主线程上调用UIImageWriteToSavedPhotosAlbum

由于任何数量的UIImageWriteToSavedPhotosAlbum任务可能按任何顺序进行,我需要一种方法来跟踪每项任务。我希望将所选单元格的indexPath存储为contextInfo,并将其传递给UIImageWriteToSavedPhotosAlbum

调用image:didFinishSavingWithError:contextInfo:时,我需要将indexPath从contextInfo中删除。

但是,UIImageWriteToSavedPhotosAlbum的绝大多数在线示例都为contextInfo传递了nil。

我已经阅读了官方文档,Swift 3指针迁移指南,头文件,使用桥接和转换的Objective-C代码,以及UnsafeMutableRawPointer / {{1的主题上的大量SO线程}}。

最终结果:我对无数选项感到困惑,并且不知道我是否遗漏了一些明显的东西,我是否应该对指针数据执行UnsafeRawPointer,应该调用load(),还是应该牺牲山羊给众神。

或者,重新评估我的职业生涯,并成为一名木匠。

Q1。如何以适合contextInfo的形式存储unsafeBitCast()的实例?

Q2。调用IndexPath后,如何从image:didFinishSavingWithError:contextInfo中构建IndexPath,以便获取我存储的数据?谢谢。

1 个答案:

答案 0 :(得分:4)

最后,谢天谢地在SO上找到了正确答案:

Swift 2 - UnsafeMutablePointer<Void> to object

基于以上答案,解决方案如下。欢迎任何改进或建议。

为了便于使用和调试,我将数据包装在引用类型中:

class ImageWritingContext : NSObject
{
    var indexPath = IndexPath()
    // ...
}

需要强有力地保存数据。在这种情况下,在数组属性中。

fileprivate var imageWritingContexts = [ImageWritingContext]()

当需要绘制时,我们将数据粘贴在包装器中并将包装器添加到数组中。

let context = ImageWritingContext()
context.indexPath = indexPath
self.imageWritingContexts.insert(context, at: 0)

现在为魔术。

let contextRawPointer = UnsafeMutableRawPointer(Unmanaged.passUnretained(self.imageWritingContexts[0]).toOpaque())

我们还在吗,我们在那吗?

let completionTarget: AnyObject = self
let completionSelector = #selector(self.image(_:didFinishSavingWithError:contextInfo:))

UIImageWriteToSavedPhotosAlbum(image,
    completionTarget,
    completionSelector,
    contextRawPointer)

回调:

func image(_ image: UIImage,
    didFinishSavingWithError error: Error?,
    contextInfo: UnsafeRawPointer)
{
    // Perform error checking here.

    // Extract the data. Pop some valium first.
    let context: ImageWritingContext = Unmanaged<ImageWritingContext>
        .fromOpaque(contextInfo)
        .takeUnretainedValue()
    let indexPath = context.indexPath

    // Do something with the data.

    // Remember to remove the context from self.imageWritingContexts!
}