Swift 3- Mettre à jour l'interface user du thread principal

Je voulais charger datatables dans le thread d'arrière-plan et mettre à jour tableview / UI sur le thread principal. Sur la base de ce qui est indiqué ici à propos de l'enfilage, je me demandais si le code ci-dessous était la bonne façon de procéder. J'essaye de charger plus de données pendant que l'user défile à un index spécifique et a voulu s'assurer que l'interface user ne gèle pas en raison du filetage. Je vous remercie!

func loadMore () { guard !self.reachedEndOfItems else { return } self.offset = self.offset! + 10 print("load more offset: \(self.offset)") var start = 0 var end = 0 isPullToRefresh = false let userCreds = UserDefaults.standard var getReqSsortingng = "" if userCreds.bool(forKey: "client_journal") == true || userCreds.bool(forKey: "user_journal") == true { var pageNum = "" if let pgNum = currentPgNum { print(pgNum) pageNum = Ssortingng(pgNum) } var filterEntryType = "" if let entryTypeStr = filtEntryType { filterEntryType = entryTypeStr } var filterUserId = "" if let userId = filtUserId { filterUserId = userId } getReqSsortingng = "https://gethealthie.com/selected_ensortinges.json?page=\(pageNum)&user_id=\(filterUserId)&entry_type=\(filterEntryType)&entry_filter=" } else { if let pgNum = currentPgNum { print(pgNum) getReqSsortingng = "https://gethealthie.com/ensortinges.json?page=\(pgNum)" } } BXProgressHUD.showHUDAddedTo(self.view) let request = Alamofire.request(getReqSsortingng, method: .get, headers: [ "access-token": userCreds.object(forKey: "access-token")! as! Ssortingng, "client": userCreds.object(forKey: "client")! as! Ssortingng, "token-type": userCreds.object(forKey: "token-type")! as! Ssortingng, "uid": userCreds.object(forKey: "uid")! as! Ssortingng, "expiry": userCreds.object(forKey: "expiry")! as! Ssortingng ]).responseJSON { (response:DataResponse<Any>) in print(response.response) let json = JSON(data: response.data!) print(json) print("yes") print(json.count) if userCreds.bool(forKey: "client_journal") == true || userCreds.bool(forKey: "user_journal") == true { self.totalEnsortinges = json["ensortinges"].count let totalEntryCount = json["ensortinges"].count start = 0 end = totalEntryCount } else { self.totalEnsortinges = json["ensortinges"].count let totalEntryCount = json["ensortinges"].count start = 0 end = totalEntryCount } if self.totalEnsortinges == 0 { BXProgressHUD.hideHUDForView(self.view); } else if end <= self.totalEnsortinges { var jourIdx = 0 let newPatient = Patient() let newDietitian = Dietitian() for i in start ..< end { let allEnsortinges = json["ensortinges"] print(allEnsortinges) print("Entry count in loadMore is \(allEnsortinges.count)") let entry = allEnsortinges[i] print(entry) let category = entry["category"] print(category) let name = entry["entry_comments"] let k = name["id"] var indexStr = Ssortingng(i) //entry atsortingbutes self.jsonIdx.add(indexStr) self.type.add(entry["type"].ssortingngValue) self.desc.add(entry["description"].ssortingngValue) self.category.add(entry["category"].ssortingngValue) //food cell- mesortingc stat == healthy int self.mesortingc_stat.add(entry["mesortingc_stat"].ssortingngValue) self.dateCreate.add(entry["created_at"].ssortingngValue) self.viewed.add(entry["viewed"].ssortingngValue) self.seenStatusArr.add(entry["viewed"].ssortingngValue) self.comments.add(entry["entry_comments"].rawValue) self.entryType.add(entry["category"].ssortingngValue) // "category" : entryType as AnyObject] let postrInfo = entry["postr"] let first = postrInfo["first_name"].ssortingngValue let last = postrInfo["last_name"].ssortingngValue let full = first + " " + last self.captionName.add(full) //food cell subcat self.hungerInt.add(entry["percieved_hungriness"].ssortingngValue) self.prehunger.add(entry["ed_prehunger_ssortingng"].ssortingngValue) self.posthunger.add(entry["ed_posthunger_ssortingng"].ssortingngValue) self.emotions.add(entry["emotions_ssortingng"].ssortingngValue) self.reflection.add(entry["reflection"].ssortingngValue) print(self.comments) self.id.add(entry["id"].ssortingngValue) self.entryImages.add(entry["image_url"].ssortingngValue) if i == end - 1 { userCreds.set(json.count, forKey: "oldJsonCount") BXProgressHUD.hideHUDForView(self.view) DispatchQueue.main.async { self.tableView.reloadData() } } } else { var reachedEndOfItems = true BXProgressHUD.hideHUDForView(self.view); print("reached the end") } } 

Dans votre exemple de code, vous reloadData la reloadData à la queue principale. Mais cela n'est pas nécessaire car la fermeture de responseJSON est déjà en cours dans la queue principale, il n'est donc pas nécessaire d'envoyer quoi que ce soit. Vous devez donc supprimer cette dissortingbution de reloadData dans la queue principale.

Maintenant, si vous utilisiez URLSession , par défaut pour exécuter des fermetures dans une queue d'arrière-plan ou si vous fournissiez explicitement une queue en tant que paramètre de queue de responseJSON , vous reloadData à la queue principale. Mais ce n'est pas la seule chose dont vous avez besoin pour vous assurer d'être envoyé dans la queue principale, car les mises à jour de votre model et les mises à jour HUD doivent également être exécutées dans la queue principale. Mais c'est discutable, parce que cette responseJSON exécute déjà son gestionnaire de complétion dans la queue principale.

Ensuite, dans les commentaires, vous requestrez plus tard si tout cela est en cours d'exécution dans la queue principale, que vous envoyiez tout cela à une queue d'arrière-plan comme dans une question précédente (sans doute pour éviter de bloquer la file principale) .

Il s'avère que cela n'est pas nécessaire (ni souhaitable) car pendant que le traitement de la réponse dans le gestionnaire de complétion responseJSON s'exécute sur la queue principale, la requête réseau, elle-même, est exécutée de manière asynchronous. Vous enverriez uniquement le code du gestionnaire d'achèvement à une queue d'arrière-plan (ou spécifiez une queue d'arrière-plan en tant que paramètre de responseJSON ) si vous étiez en train de faire quelque chose de calcul intensif dans la fermeture. Mais vous n'avez pas à vous soucier de la request réseau bloquant la queue principale.

Bottom line, Alamofire rend cela simple pour vous, il exécute la requête de manière asynchronous, mais exécute ses gestionnaires d'achèvement sur la queue principale. Il élimine une grande partie du code GCD manuel que vous URLSession lors de l'utilisation d' URLSession .