【问题标题】:Warning: A long-running operation is being executed on the main thread. try! get data(). Swift警告:正在主线程上执行长时间运行的操作。尝试!获取数据()。迅速
【发布时间】:2016-02-16 19:31:28
【问题描述】:

我知道错误来自try! converyPFFile.getData()

如果我不想在后台获取数据,想知道如何消除错误,因为如果我在后台获取数据,则无法将图像附加到数组中。谢谢。

        query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error: NSError?) -> Void in
            for object in objects! {
                self.senderArray.append(object.objectForKey("sender") as! String)
                self.messageArray.append(object.objectForKey("message") as? String)
                if object.objectForKey("photo") != nil {
                    if let converyPFFile = object.objectForKey("photo") as? PFFile{
                        let temp = try! converyPFFile.getData()
                        let image = UIImage(data: temp)
                        self.photoArray.append(image)
                    }
                } else {
                    self.photoArray.append(nil)
                }
            }
            // create a chat interface
            if self.senderArray[i] == self.userName {
                if self.messageArray[i] != nil {
                    // using scroll view
                    // create username label
                    // create message text label
                } else { 
                    // using scroll view
                    // create username label
                    // create message image
                    messageImage.image = self.photoArray[i]
                }
                ....

【问题讨论】:

    标签: arrays swift image parse-platform try-catch


    【解决方案1】:

    我发现这个警告来自 Parse。您可以通过使用getDataInBackgroundWithBlock 来克服它,然后在该块中附加到您的数组。因此,您的代码变得类似于(未经测试,我认为我的大括号配对错误):

        query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error: NSError?) -> Void in
            for object in objects! {
                self.senderArray.append(object.objectForKey("sender") as! String)
                self.messageArray.append(object.objectForKey("message") as? String)
                if object.objectForKey("photo") != nil {
                    if let converyPFFile = object.objectForKey("photo") as? PFFile{
                        converyPFFile.getDataInBackgroundWithBlock { (data: NSData!, error: NSError!) -> Void in
                        let image = UIImage(data: data)
                        self.photoArray.append(image)
                    }
                } else {
                    self.photoArray.append(nil)
                }
            }
            // create a chat interface
            if self.senderArray[i] == self.userName {
                if self.messageArray[i] != nil {
                    // create username label
                    // create message text label
                } else { 
                    // create username label
                    // create message image
                    messageImage.image = self.photoArray[i]
                }
                ....
    

    【讨论】:

    • 如果我在后台执行,如果我在下面创建消息图像,图像将无法显示。
    • 我假设您在 UITableView(或 UICollectionView)中显示图像?将图像添加到数组后,只需在主线程上调用 tableView.reloadData()
    • 我在滚动视图中定位标签和图像。
    • 所以你需要在getData之后重置messageImage.image。您已经使用findObjectsInBackgroundWithBlock 在后台线程上运行,因此无论如何您都必须处理异步负载。另外,你为什么不使用 UICollectionView?从您发布的代码看来,您正在尝试使用 UIScrollView 实现相同的效果。
    • findobjectsInBackgroundWithBlock 不是问题,因为我也在其中创建了聊天界面。我不使用表格视图或集合视图的原因是因为我想尝试一种新的方法来做同样的事情,就像我是 Xcode 的初学者一样。那么,根据我的代码,我该如何使用异步加载?
    【解决方案2】:

    可以在后台执行您的任务,同时仍确保附加到您的照片数组是在主线程上完成的。 您只需将该特定代码分派到主线程即可。 请参阅下面的示例:

        query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error: NSError?) -> Void in
            for object in objects! {
                self.senderArray.append(object.objectForKey("sender") as! String)
                self.messageArray.append(object.objectForKey("message") as? String)
                if object.objectForKey("photo") != nil {
                    if let converyPFFile = object.objectForKey("photo") as? PFFile{
                        let temp = try! converyPFFile.getData()
                        let image = UIImage(data: temp)
                        // this will cause self.photoArray.append to be executed on the main thread
                        dispatch_async(dispatch_get_main_queue(),{
                            self.photoArray.append(image)
                        })
                    }
                } else {
                    // this will cause self.photoArray.append to be executed on the main thread
                    dispatch_async(dispatch_get_main_queue(),{
                        self.photoArray.append(nil)
                    })
                }
            }
            // create a chat interface
            if self.senderArray[i] == self.userName {
                if self.messageArray[i] != nil {
                    // create username label
                    // create message text label
                } else {
                    // create username label
                    // create message image
                    messageImage.image = self.photoArray[i]
        }
    

    【讨论】:

    • 如果我将照片数组附加到主线程上,我会收到此错误“致命错误:数组索引超出范围”
    • 这可能是因为您在同一方法中的其他地方使用了 self.photoArray。这通常发生在您在一个线程中循环其内容(对于 self.photoArray ... 中的照片)并同时在另一个线程上添加或删除数组中的项目时。如果是这种情况,那么您要么需要在修改 photoArray 时处理 self.photoArray 的副本,要么必须将代码与 dispatch_groups 的信号量同步,以确保编辑 self.photoArrays 的所有代码在您之前完成开始在另一个线程中使用 self.photoArray。
    猜你喜欢
    • 1970-01-01
    • 2015-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多