ios - 为什么我的应用程序在我将数据上传到 Firebase 时卡住?

标签 ios swift firebase grand-central-dispatch background-thread

更新 ****小编辑,我发现实际上唯一卡住的是从 firebase 检索数据,尤其是需要检索的图像。 func initOberserver 用于从 firebase 检索数据。所以这需要每次都在后台完成。但是 tableview 必须同时可用?****

我在后台线程方面遇到了一些困难。我正在制作一个 firebase 应用程序,但当我将某些内容上传到 firebase 并将其检索回应用程序时,我的应用程序会卡住一段时间。

我在一个单独的打开文件中有 2 个常量:

let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)

我有一个 View Controller :ListVC,它使用此函数从 firebase 检索数据。

func initObservers() {

    //LoadingOverlay.shared.showOverlay(self.view)
    dispatch_async(backgroundQueue, {
        DataService.ds.REF_LISTS.observeEventType(.Value, withBlock: { snapshot in
            print(snapshot.value)

            self.lists = []

            if let snapshots = snapshot.children.allObjects as? [FDataSnapshot] {

                for snap in snapshots {
                    print("SNAP: \(snap)")

                    if let listDict = snap.value as? Dictionary<String, AnyObject> {
                        let key = snap.key
                        let list = List(listKey: key, dictionary: listDict)
                        self.lists.insert(list, atIndex:0)
                    }
                }
            }

            //LoadingOverlay.shared.hideOverlayView()
            self.tableView.reloadData()

        })

    })

}

然后我有一个 View Controller addVC,它使用此函数将数据发布到 firebase:

@IBAction func postListItem(sender: AnyObject) {

        if let addTitle = addTitle.text where addTitle != "", let addDescription = addDescription.text where addDescription != "", let addLocation = addLocation.text where addLocation != "" {

            dispatch_async(backgroundQueue, {
                self.postToFirebase(nil)

                dispatch_async(dispatch_get_main_queue(), { () -> Void in

                    let storyboard = UIStoryboard(name: "Main", bundle: nil)
                    let listVC = storyboard.instantiateViewControllerWithIdentifier("TBC") as! UITabBarController
                    listVC.selectedIndex = 1
                    self.presentViewController(listVC, animated: false, completion: nil)
                })
            })
        }
    }

func postToFirebase(imgUrl: String?) {

        LoadingOverlay.shared.showOverlay(self.overlayView)

        var post: Dictionary<String, AnyObject> = ["username": currentUsername, "description": addDescription.text!, "title": addTitle.text!, "location": addLocation.text!, "images": self.base64String]

        let firebasePost = DataService.ds.REF_LISTS.childByAutoId()
        firebasePost.setValue(post)

    }

如您所见,我使用在 Internet 和 Stack Overflow 上找到的代码和解释进行了尝试。但是,如果我打开我的应用程序并转到 listVC,它会在 2 秒后卡住大约 10 秒,而当我发布内容时,它也会在转到 listVC 时卡住一段时间。

我还有这段代码:

let uploadImage = image
        let imageData = UIImageJPEGRepresentation(uploadImage, 0.5)
        self.base64String = imageData!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength)

没有这段代码,它不会卡住,它会在几秒钟内完成“这就是事情”。但我需要此代码才能将图像发布到 firebase?

最佳答案

让我们简化一下 - 这是概念性的,但可能会有所帮助。

首先,填充 tableView 数据源。有一种更好的方法来初始填充数据源并重新加载 tableView,因此假设您只有一个小数据集用于此示例。

self.lists = []

DataService.ds.REF_LISTS.observeEventType(.ChildAdded, withBlock: { snapshot in
  self.lists.insert(snapshot.value, atIndex:0)
  self.tableView.reloadData //this is for example only
}

现在稍后,例如,在您的 IBAction 中,将一些数据写入 Firebase

var post: Dictionary<String, AnyObject> = ["username": currentUsername, "description": addDescription.text!, "title": addTitle.text!, "location": addLocation.text!, "images": self.base64String]

let firebasePost = DataService.ds.REF_LISTS.childByAutoId()
firebasePost.setValue(post)

从这里开始,只要将 Firebase 数据写入观察节点,您的应用就会收到新数据通知,并将其添加到数据源和 tableView 更新。

如果您需要先加载一个 tableview,然后再观察 .childAdded 事件,这里有一个技巧。

var lastNamesArray = [String]()
var initialLoad = true

//add observers so we load the current lastNames and are aware of any
// lastName additions

peopleRef.observeEventType(.ChildAdded, withBlock: { snapshot in

  let lastName = snapshot.value["last_name"] as? String      
  self.lastNamesArray.append(lastName)

  //upon first load, don't reload the tableView until all children are loaded
  if ( self.initialLoad == false ) {
    self.lastNamesTableView.reloadData()
  }
})

//this .Value event will fire AFTER the child added events to reload the tableView 
//  the first time and to set subsequent childAdded events to load after each
//  child is added in the future

peopleRef.observeSingleEventOfType(.Value, withBlock: { snapshot in

    print("inital data loaded so reload tableView!  /(snapshot.childrenCount)")
    self.lastNamesTableView.reloadData()
    self.initialLoad = false        
})

关于ios - 为什么我的应用程序在我将数据上传到 Firebase 时卡住?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37010291/

相关文章:

objective-c - NSScanner - 性能缓慢 - (UITableView, NSXMLParser)

ios - 限制用户可以在 Parse 上存储的图像数量

ios - 尝试将用户电子邮件和姓名保存到 Firebase 数据库时出现异常

ios - CKFetchRecordChangesOperation首先返回垃圾数据

ios - 读取核心数据时出错 : ios swift

ios - 嵌套表格和 Collection View 的 self 调整单元格

macos - 如何在 OS X 上的 Swift 中创建 VPN 连接?

swift - 如何在 UITextView 中使用 NSMutuableAttributedString?

firebase - firebase 在哪里保存它的简单登录用户?

ios - 尝试使用 Swift 3 从 Firebase 检索数据时出现问题