无法从循环内的异步调用修改表视图dataSource

时间:2016-08-20 02:13:06

标签: ios swift asynchronous

当所有异步调用在循环内完成时,我尝试在dataSource完成更新后重新加载TableView。但是,看起来postLike.likeUser在范围之外变得清晰。

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

    }

}

从异步调用更新dataSource的更好方法是什么

更新

我使用调度组修改了我的代码,但结果是一样的,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

1 个答案:

答案 0 :(得分:0)

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