显示从本地文件加载的UIImageView的长时间延迟?

时间:2015-09-07 21:23:15

标签: ios swift uiimageview nskeyedunarchiver

我看到有关下载后显示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()
}

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

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

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

更新:根据评论,我根据Leo Dabus的建议在dispatch_async中附上了needsDisplay代码,并根据Paulw11进行了一些时间分析。链接到时间分析结果在这里:https://i.imgur.com/sa5qfRM.png我在1点左右图像出现在屏幕上后立即停止了分析,但它实际上是在20s左右的凹凸处“加载”。在那段时间里似乎什么都没发生......?代码实际上只是等了一会儿?

为了清楚我是如何实现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。将此留给其他人......

0 个答案:

没有答案