简体   繁体   English

Swift,NSOperationQueue.mainQueue():在运行过程中更新运行中的数据?

[英]Swift, NSOperationQueue.mainQueue(): update data in operation during operation is running?

I use background file downloading in IOS project, and when file downloading is started, progress view's update is started by block NSOperationQueue.mainQueue().addOperationWithBlock() in method: 我在IOS项目中使用后台文件下载,并且在开始文件下载时,通过方法中的块NSOperationQueue.mainQueue().addOperationWithBlock()启动进度视图的更新:

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
    if totalBytesExpectedToWrite == NSURLSessionTransferSizeUnknown {
       println("Unknown transfer size");
    }
     else{
       let data = getDBInfoWithTaskIdentifier(downloadTask.taskIdentifier)

       NSOperationQueue.mainQueue().addOperationWithBlock(){
           data.db_info.downloadProgress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
            let inf = data.db_info.indexPath
            let cell = self.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: data.index, inSection: 0)) as SettingsTableViewCell
            cell.downloadProgress.hidden = false
            cell.downloadProgress.setProgress(data.db_info.downloadProgress, animated: true)
        }
    }
}

When view with download UI is dismissed and present once more, self.tableView is new object, but self.tableView in NSOperationQueue.mainQueue() operation, which update progress view, is old one, that what was before dismissing. 当关闭带有下载UI的视图并再次显示该视图时, self.tableView是新对象,但是更新进度视图的NSOperationQueue.mainQueue()操作中的self.tableView是旧的,即关闭前的状态。 Println() returns two different objects. Println()返回两个不同的对象。 Is there possibility update data about self.tableView in that NSOperationQueue.mainQueue() block? NSOperationQueue.mainQueue()块中是否有可能更新有关self.tableView数据?

First of all you should consider switch to GCD (Grand Central Dispatch). 首先,您应该考虑切换到GCD(大中央调度)。

Your problem arises because the reference to the tableView is captured in the closure. 出现问题是因为在闭包中捕获了对tableView的引用。 You can consider to put the logic in a separate class function so tableView is not exposed in your closure. 您可以考虑将逻辑放在单独的类函数中,这样tableView不会在您的闭包中公开。 It has an added benefit of cleaner, more organised code. 它具有更简洁,更有条理的代码的另一个好处。

Here is a general idea: 这是一个总体思路:

// new function
func setProgressInCell (data:?) { // '?' because i do not know the type
    let inf = data.db_info.indexPath
    let cell = self.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: data.index, inSection: 0)) as SettingsTableViewCell
    cell.downloadProgress.hidden = false
    cell.downloadProgress.setProgress(data.db_info.downloadProgress, animated: true)

}

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
    if totalBytesExpectedToWrite == NSURLSessionTransferSizeUnknown {
       println("Unknown transfer size");
    }
     else{
       let data = getDBInfoWithTaskIdentifier(downloadTask.taskIdentifier)

       dispatch_async(dispatch_get_main_queue())  {
           [weak self] in
           data.db_info.downloadProgress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
           self.setProgressInCell(data)

        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM