gpt4 book ai didi

ios - 无法通过循环内的异步调用修改 TableView 数据源

转载 作者:行者123 更新时间:2023-11-30 13:08:33 25 4
gpt4 key购买 nike

当所有异步调用在循环内完成时,我尝试在数据源完成更新后重新加载 TableView。然而,似乎 postLike.likeUser 在 for 范围之外变得清晰。

class MyTableView: UITableViewController {
let reuseIden = "postLikeCell"

var postLikes: [PostLike]?

var userFetchingCompleted = false

var userFetched: Int = 0

override func viewDidLoad() {
super.viewDidLoad()
startFetchingLikeUsers()
}

func startFetchingLikeUsers(){
if postLikes != nil{
for (index, postLike) in postLikes!.enumerate(){
postLike.likeUser = User(id: postLike.likeUserId, completionHandler: {
// the User initilizer requires to fetch info from the server
(succeed, info) in
if succeed{
self.userFetched += 1
print(self.userFetched)
print(self.postLikes![index].likeUser?.fullname)

if self.userFetched == self.postLikes!.count{
self.userFetchingCompleted = true
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})
}
}
})
}
}
}


// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return userFetchingCompleted ? (postLikes?.count ?? 0) : 0
}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("postLikeCell", forIndexPath: indexPath) as! PostLikeTableViewCell
print(postLikes![indexPath.row].likeUser) //always print nil
cell.postLike = postLikes![indexPath.row]
return cell
}


}

上面代码的示例输出是

1   //the first iteration
Optional("Nicholas Tse")
user get cleared //it seems the postLike.likeUser gets deInitialized since I have a deInit in my User class

2 //second iteration
Optional("Kesong Xie")
user get cleared

nil //this comes from cellForRowAtIndex
nil

我对 PostLike 类的实现

class PostLike{
let postLikeId: Int
let likeTime: String
let likeUserId: Int
unowned var post: Post
weak var likeUser: User? //the user who liked the post


init(postLikeId: Int, likeTime: String, likeUserId: Int, post: Post){
self.postLikeId = postLikeId
self.likeTime = likeTime
self.likeUserId = likeUserId
self.post = post

}

}

从异步调用更新数据源的更好方法是什么

更新

我已经使用调度组修改了我的代码,但结果是相同的,postLike.likeUser 被清除了

func startFetchingLikeUsers(completionHandler: () -> Void){
if postLikes != nil{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), { //don't block the main thread
let loadingGroup = dispatch_group_create()

for (index, postLike) in self.postLikes!.enumerate(){
dispatch_group_enter(loadingGroup)
postLike.likeUser = User(id: postLike.likeUserId, completionHandler: {
(succeed, info) in
dispatch_group_leave(loadingGroup)
print( self.postLikes![index].likeUser?.fullname)
})
self.postLikes![index].likeUser = postLike.likeUser
}

dispatch_group_wait(loadingGroup, DISPATCH_TIME_FOREVER)
dispatch_async(dispatch_get_main_queue(), {
completionHandler()
})
})
}
}

输出:

Optional("Nicholas Tse")
user get cleared
Optional("Kesong Xie")
user get cleared
nil
nil

最佳答案

postLike.likeUser 总是被释放的原因是,在我的 PostLike 实现中,我有 weak var likeUser: User?。当 postLike.likeUser 超出循环范围时,并且由于没有对 User 对象的强引用,因此 User 会被释放。将 weak var likeUser: User? 更改为 var likeUser! 将解决该问题。

class PostLike{
let postLikeId: Int
let likeTime: String
let likeUserId: Int
unowned var post: Post
var likeUser: User! //the user who liked the post


init(postLikeId: Int, likeTime: String, likeUserId: Int, post: Post){
self.postLikeId = postLikeId
self.likeTime = likeTime
self.likeUserId = likeUserId
self.post = post

}
}

输出

Optional("Nicholas Tse")
Optional("Kesong Xie")
Optional("Nicholas Tse")
Optional("Kesong Xie")

关于ios - 无法通过循环内的异步调用修改 TableView 数据源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39049822/

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