gpt4 book ai didi

ios - Swift 3-从主线程更新 UI

转载 作者:行者123 更新时间:2023-11-30 12:46:58 28 4
gpt4 key购买 nike

我想在后台线程中加载数据并在主线程上更新 tableview/UI。根据指示 here关于线程,我想知道下面的代码是否是解决问题的方法。我试图在用户滚动到特定索引时加载更多数据,并希望确保 UI 不会因线程而卡住。谢谢!

 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 getReqString = ""


if userCreds.bool(forKey: "client_journal") == true || userCreds.bool(forKey: "user_journal") == true {

var pageNum = ""
if let pgNum = currentPgNum {
print(pgNum)
pageNum = String(pgNum)
}
var filterEntryType = ""
if let entryTypeStr = filtEntryType {
filterEntryType = entryTypeStr
}

var filterUserId = ""
if let userId = filtUserId {
filterUserId = userId

}

getReqString = "https://gethealthie.com/selected_entries.json?page=\(pageNum)&user_id=\(filterUserId)&entry_type=\(filterEntryType)&entry_filter="


} else {

if let pgNum = currentPgNum {
print(pgNum)

getReqString = "https://gethealthie.com/entries.json?page=\(pgNum)"
}

}


BXProgressHUD.showHUDAddedTo(self.view)
let request = Alamofire.request(getReqString, method: .get, headers: [
"access-token": userCreds.object(forKey: "access-token")! as! String,
"client": userCreds.object(forKey: "client")! as! String,
"token-type": userCreds.object(forKey: "token-type")! as! String,
"uid": userCreds.object(forKey: "uid")! as! String,
"expiry": userCreds.object(forKey: "expiry")! as! String
]).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.totalEntries = json["entries"].count

let totalEntryCount = json["entries"].count
start = 0
end = totalEntryCount
} else {
self.totalEntries = json["entries"].count

let totalEntryCount = json["entries"].count
start = 0
end = totalEntryCount
}

if self.totalEntries == 0 {
BXProgressHUD.hideHUDForView(self.view);

} else if end <= self.totalEntries {
var jourIdx = 0

let newPatient = Patient()
let newDietitian = Dietitian()


for i in start ..< end {


let allEntries = json["entries"]
print(allEntries)
print("Entry count in loadMore is \(allEntries.count)")

let entry = allEntries[i]
print(entry)

let category = entry["category"]
print(category)


let name = entry["entry_comments"]
let k = name["id"]


var indexStr = String(i)

//entry attributes
self.jsonIdx.add(indexStr)

self.type.add(entry["type"].stringValue)
self.desc.add(entry["description"].stringValue)
self.category.add(entry["category"].stringValue)
//food cell- metric stat == healthy int
self.metric_stat.add(entry["metric_stat"].stringValue)
self.dateCreate.add(entry["created_at"].stringValue)
self.viewed.add(entry["viewed"].stringValue)
self.seenStatusArr.add(entry["viewed"].stringValue)
self.comments.add(entry["entry_comments"].rawValue)
self.entryType.add(entry["category"].stringValue)
// "category" : entryType as AnyObject]

let posterInfo = entry["poster"]
let first = posterInfo["first_name"].stringValue
let last = posterInfo["last_name"].stringValue
let full = first + " " + last
self.captionName.add(full)


//food cell subcat
self.hungerInt.add(entry["percieved_hungriness"].stringValue)
self.prehunger.add(entry["ed_prehunger_string"].stringValue)
self.posthunger.add(entry["ed_posthunger_string"].stringValue)
self.emotions.add(entry["emotions_string"].stringValue)
self.reflection.add(entry["reflection"].stringValue)


print(self.comments)
self.id.add(entry["id"].stringValue)
self.entryImages.add(entry["image_url"].stringValue)


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")
}

}

最佳答案

在此处的代码示例中,您将 reloadData 分派(dispatch)到主队列。但这是不必要的,因为 responseJSON 的关闭已经在主队列上运行,因此不需要分派(dispatch)任何内容。因此,您应该删除对主队列的 reloadData 分派(dispatch)。

现在,如果您使用 URLSession,它默认在后台队列上运行闭包,或者如果您明确提供后台队列作为 queue 参数responseJSON,然后,是的,您可以将 reloadData 分派(dispatch)到主队列。但这并不是您需要确保分派(dispatch)到主队列的唯一事情,因为您的模型更新和 HUD 更新也应该在主队列上运行。但这是没有意义的,因为这个 responseJSON 已经在主队列上运行其完成处理程序。

然后,在评论中,您稍后会询问所有这些是否都在主队列上运行,是否应该像 a previous question 中那样将所有这些都分派(dispatch)到后台队列(大概是为了避免阻塞主队列)。

事实证明,这是不必要的(也不可取的),因为虽然 responseJSON 完成处理程序中的响应处理在主队列上运行,但网络请求本身是异步执行的。如果您在闭包中执行计算密集型操作,则仅将完成处理程序代码分派(dispatch)到后台队列(或将后台队列指定为 responseJSON 的参数)。但你不必担心网络请求阻塞主队列。

底线,Alamofire 让这一切变得简单,它异步运行请求,但在主队列上运行其完成处理程序。它消除了您在使用 URLSession 时困惑的大量手动 GCD 代码。

关于ios - Swift 3-从主线程更新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41524332/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com