我有一个UITableView. 当一个单元格被点击时,我的应用程序会生成一个相关的图像。图像生成是在后台线程上完成的,因为有些图像需要相当长的时间来渲染。渲染图像后,UIImageWriteToSavedPhotosAlbum在主线程上调用。
由于任何数量的UIImageWriteToSavedPhotosAlbum任务可能以任何顺序进行,我需要一种方法来跟踪每个任务。我希望indexPath将所选单元格的存储为contextInfo,将其传递给UIImageWriteToSavedPhotosAlbum.
当image:didFinishSavingWithError:contextInfo:被调用时,我需要从 contextInfo 中获取 indexPath。
但是,绝大多数在线示例UIImageWriteToSavedPhotosAlbum通过 nil for contextInfo.
我已经阅读了官方文档、Swift 3 指针迁移指南、头文件、使用桥接和强制转换的 Objective-C 代码,以及许多关于UnsafeMutableRawPointer/主题的 SO 线程UnsafeRawPointer。
最终结果:我被无数的选择弄糊涂了,不知道我是否遗漏了一些明显的东西,我是否应该load()在指针数据上执行,应该调用unsafeBitCast(),还是应该将山羊献给众神。
或者,重新评估我的职业生涯,成为一名木匠。
一季度。如何IndexPath以适合 contextInfo 的形式存储 的实例?
Q2。一旦image:didFinishSavingWithError:contextInfo被调用,我如何形成一个IndexPathout of contextInfo,以便获取我存储的数据?谢谢你。
最后,幸运的是偶然发现了一个关于 SO 的正确答案:
Swift 2 - UnsafeMutablePointer<Void> 到对象
基于上述答案,解决方案如下。欢迎任何改进或建议。
为了便于使用和调试,我将数据包装在引用类型中:
class ImageWritingContext : NSObject
{
var indexPath = IndexPath()
// ...
}
Run Code Online (Sandbox Code Playgroud)
数据需要牢固地保存。在这种情况下,在数组属性中。
fileprivate var imageWritingContexts = [ImageWritingContext]()
Run Code Online (Sandbox Code Playgroud)
当需要绘制时,我们将数据粘贴在包装器中并将包装器添加到数组中。
let context = ImageWritingContext()
context.indexPath = indexPath
self.imageWritingContexts.insert(context, at: 0)
Run Code Online (Sandbox Code Playgroud)
现在是魔法。
let contextRawPointer = UnsafeMutableRawPointer(Unmanaged.passUnretained(self.imageWritingContexts[0]).toOpaque())
Run Code Online (Sandbox Code Playgroud)
我们到了吗,我们到了吗?
let completionTarget: AnyObject = self
let completionSelector = #selector(self.image(_:didFinishSavingWithError:contextInfo:))
UIImageWriteToSavedPhotosAlbum(image,
completionTarget,
completionSelector,
contextRawPointer)
Run Code Online (Sandbox Code Playgroud)
回调:
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!
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1601 次 |
| 最近记录: |