[英]Why does adding multisampling to my app freeze the screen on the first frame?
[英]Why does my app freeze while I upload data to firebase?
更新: ****很少編輯,我發現實際上唯一凍結的是從firebase中檢索數據,尤其是需要檢索的圖像。 func initOberserver用於從firebase檢索數據。 因此,需要每次在后台執行此操作。 但tableview必須在此期間可用?****
我在后台線程方面有些掙扎。 我正在制作一個Firebase應用程序,但是當我將某些內容上傳到Firebase並將其取回該應用程序時,我的應用程序凍結了一段時間。
我在一個單獨的打開文件中有2個常量:
let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
我有一個viewcontroller: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()
})
})
}
然后我有一個視圖控制器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數據源。 有一種更好的方法來初始填充dataSource並重新加載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數據寫入觀察到的節點,您的應用程序就會收到有關該新數據的通知,並將其添加到dataSource和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
})
在您的最后一個函數postToFirebase
,您在后台線程下執行了一個UI操作,看來這是您的錯誤。
LoadingOverlay.shared.showOverlay(self.overlayView)
正如在問題下方的注釋中所寫,在名為initObservers
的第一個函數結尾處, reloadData()
發生了同樣的事情。
強烈建議不要從后台線程(例如,計時器,通信等)更新UI控件等。 這可能是導致崩潰的原因,有時很難識別。 而是使用它們來強制在UI線程(始終是“主”線程)上執行代碼。
dispatch_async(dispatch_get_main_queue()) {
// this code will be running on the main thread
}
更新 :關於您對UIImageJPEGRepresentation
的最后一個問題,這是一個如何啟動它的示例:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
let getImage = UIImage(data: NSData(contentsOfURL: NSURL(string: self.remoteImage)))
UIImageJPEGRepresentation(getImage, 100).writeToFile(imagePath, atomically: true)
dispatch_async(dispatch_get_main_queue()) {
self.image?.image = getImage
return
}
}
DispatchQueue.global(attributes: .qosBackground).async {
print("This is run on the background queue")
DispatchQueue.main.async {
print("This is run on the main queue, after the previous code in outer block")
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.