UIActivityIndicatorView 在异步任务期间未显示
Posted
技术标签:
【中文标题】UIActivityIndicatorView 在异步任务期间未显示【英文标题】:UIActivityIndicatorView not showing for duration of async task 【发布时间】:2015-08-14 15:16:30 【问题描述】:我正在开发一个 ios 应用程序,其中我需要开始旋转 UIActivityIndicatorView,将图像上传到服务器,上传完成后,停止旋转活动指示器。
我目前正在使用 XCode 7 Beta 并在 iOS 模拟器上测试该应用程序作为 iPhone 6 和 iPhone 5。我的问题是活动指示器不会在文件上传后立即结束,而是几个(约 28 秒) 之后。我应该在哪里拨打电话以使其结束?
我在用于启动进程的按钮上附加了一个@IBOutlet 函数,该函数包含 startAnimating() 函数,并调用包含对 uploadImage 的调用的 dispatch_async 方法,该方法包含信号、等待和 stopAnimating () 函数。
注意
let semaphore = dispatch_semaphore_create(0)
let priority = DISPATCH_QUEUE_PRIORITY_HIGH
在我的班级顶部定义。
@IBAction func uploadButton(sender: AnyObject)
self.activityIndicatorView.startAnimating()
dispatch_async(dispatch_get_global_queue(priority, 0))
self.uploadImage(self.myImageView.image!)
// end dispatch_async
// works with startAnimating() and stopAnimating() in async but not with uploadImage() in async
func uploadImage(image: UIImage)
let request = self.createRequest(image)
let session : NSURLSession = NSURLSession.sharedSession()
let task : NSURLSessionTask = session.dataTaskWithRequest(request, completionHandler:
(data, response, error) in
if error != nil
print(error!.description)
else
let httpResponse: NSHTTPURLResponse = response as! NSHTTPURLResponse
if httpResponse.statusCode != 200
print(httpResponse.description)
else
print("Success! Status code == 200.")
dispatch_semaphore_signal(self.semaphore)
)! // end dataTaskWithResult
task.resume()
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER)
self.activityIndicatorView.stopAnimating()
// end uploadImage
这只是我的代码的一个版本,我已经以几种不同的方式移动了一些东西。我试过这个:
@IBAction func uploadButton(sender: AnyObject)
self.activityIndicatorView.startAnimating()
dispatch_async(dispatch_get_global_queue(priority, 0))
self.uploadImage(self.myImageView.image!)
dispatch_semaphore_signal(self.semaphore)
// end dispatch_async
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER)
self.activityIndicatorView.stopAnimating()
还有其他几种移动我的代码的方法,以尝试在图像上传期间显示活动指示器,然后立即退出。在某些情况下,微调器在程序执行期间根本不会出现。我阅读了this 帖子和this 问题,并已将我的 dispatch_semaphore_wait 和 stopAnimating() 迁移到 uploadImage() 方法以规避此问题,但在 UIActivityIndicatorView 文档中找不到有关 UI 更新的足够信息以了解任何其他方式更新它,尽管我相信这可能是问题的核心。
我所需要的只是让微调器在上传过程开始(dataTaskWithRequest)之前启动,并在它成功或失败后结束。我做错了什么?
【问题讨论】:
【参考方案1】:您可以直接分派到异步任务中的主线程,而不是使用信号量,
func uploadImage(image: UIImage)
let request = self.createRequest(image)
let session : NSURLSession = NSURLSession.sharedSession()
let task : NSURLSessionTask = session.dataTaskWithRequest(request, completionHandler:
(data, response, error) in
if error != nil
print(error!.description)
else
let httpResponse: NSHTTPURLResponse = response as! NSHTTPURLResponse
if httpResponse.statusCode != 200
print(httpResponse.description)
else
print("Success! Status code == 200.")
// dispatch to main thread to stop activity indicator
dispatch_async(disptach_get_main_queue())
self.activityIndicatorView.stopAnimating()
)! // end dataTaskWithResult
task.resume()
// end uploadImage
【讨论】:
这解决了这个问题,尽管我对信号量无法正常工作的原因感到非常沮丧。我的代码中有原因吗? 我对信号量知之甚少,无法回答这个问题。由于我的知识有限,您的代码看起来不错。但有时 GCD 只是让生活更轻松。 我不认为您使用的信号量代码会导致在主线程上执行对self.activityIndicatorView.stopAnimating
的调用。基思使用dispatch_async(disptach_get_main_queue()
的解决方案是正确答案。 (已投票)
解决方案对同步请求无效。如果有人想使用信号量进行同步调用怎么办。同样的问题会再次出现。以上是关于UIActivityIndicatorView 在异步任务期间未显示的主要内容,如果未能解决你的问题,请参考以下文章
UIActivityIndi catorView未在webview中显示
UIButton里面的UIActivityIndicatorView
Swift UIPageViewController & UIActivityIndicatorView
如何在 UIAlertView 的中心添加 UIActivityIndicatorView?