0

我看到有关下载后显示 UIImageViews 的长时间延迟的问题,但我的问题涉及从本地存储读取时的长时间延迟。

将我的 UIImageViews 层次结构归档到本地文件后(根据 narohi 在 How to output a view hierarchy & contents to file?中的回答),我发现如果我想重新加载它们,视图实际上需要 5 到 20 秒尽管我在主视图和所有子视图上设置了 setNeedsDiplay() ,但仍出现在屏幕上。

我可以立即查询加载的 UIView 的自定义子类中包含的数据——显示 NSKeyedUnarchiver 和所有 NS 解码以及所有 init() 都已完成——但是图像只是没有出现在屏幕上需很长时间。下一个重绘周期肯定会短于 5-20 秒...?

来自 PhotoLibrary 的图像立即出现似乎很奇怪,但使用 NSKeyedUnarchiver 从本地文件存储加载的任何内容都需要“永远”。

这是怎么回事,我怎样才能加快速度?

.

.

明确地说,我的 Swift 代码的相关部分如下所示:

let view = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as! UIView!
if (nil == view) {
   return
}
myMainView.addSubview(view)
view.setNeedsDisplay()
// now do things with the data in view ...which all works fine

我发现,即使我添加类似...

for subview in view.subviews {
    subview.setNeedsDisplay()
}

...它不会加快操作速度。

我们也不是在谈论巨大的数据集,它可能只是一个正在重新加载的图像视图。

现在,我也注意到使用下载器从 Internet 下载时会出现这些延迟,例如 https://stackoverflow.com/a/28221670/4259243中所示的下载器 ......但我让下载器打印完成消息后不仅下载但是当(同步操作)data.writeToFile() 完成时(并且在我尝试使用 NSKeyedUnarchiver 加载它之前),所以这表明 UIImageView 重绘的延迟不是因为下载仍在开始......和就像我说的,你可以查询数据的属性,它都在内存中,只是不显示在屏幕上。

更新: 根据评论,我已根据 Leo Dabus 的建议在 dispatch_async 中包含了 needsDisplay 代码,并根据 Paulw11 进行了一些时间分析。时间分析结果的链接在这里:https ://i.imgur.com/sa5qfRM.png 我在 1:00 左右图像出现在屏幕上后立即停止了分析,但它实际上是在颠簸期间“加载”的20 多岁。那段时间好像什么都没有发生……?代码实际上只是在等待一段时间?

为了清楚我是如何实现 dispatch_async 的,请看这里:

func addViewToMainView(path: String) {
    let view = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as! UIView!
    if (nil == view) {
       return
    }
    dispatch_async(dispatch_get_main_queue(), {
       self.myMainView.addSubview(view)
       view.setNeedsDisplay()
       self.myMainView.setNeedsDisplay()
    })
}

...自从发布此消息以来,我发现了一些人们抱怨 NSKeyedUnarchiver 有多慢的帖子。难道就这样吗?如果是这样, :-(。

第二次更新:啊,“let view =”需要在 dispatch_async 中。事实上,如果你只是把整个东西放在 dispatch_async 中,它就可以很好地工作!所以...

func addViewToMainView(path: String) {
    dispatch_async(dispatch_get_main_queue(), {
        let view = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as! UIView!
        if (nil == view) {
           return
        }

       self.myMainView.addSubview(view)
       view.setNeedsDisplay()
       self.myMainView.setNeedsDisplay()
    })
}

这立即起作用。哇.. 归功于 Leo Dabus。把这个留给其他人...

4

0 回答 0