UIActivityIndi​​catorView 在异步任务期间未显示

Posted

技术标签:

【中文标题】UIActivityIndi​​catorView 在异步任务期间未显示【英文标题】:UIActivityIndicatorView not showing for duration of async task 【发布时间】:2015-08-14 15:16:30 【问题描述】:

我正在开发一个 ios 应用程序,其中我需要开始旋转 UIActivityIndi​​catorView,将图像上传到服务器,上传完成后,停止旋转活动指示器。

我目前正在使用 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() 方法以规避此问题,但在 UIActivityIndi​​catorView 文档中找不到有关 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() 的解决方案是正确答案。 (已投票) 解决方案对同步请求无效。如果有人想使用信号量进行同步调用怎么办。同样的问题会再次出现。

以上是关于UIActivityIndi​​catorView 在异步任务期间未显示的主要内容,如果未能解决你的问题,请参考以下文章

UIActivityIndi catorView未在webview中显示

UIButton里面的UIActivityIndi​​catorView

Swift UIPageViewController & UIActivityIndi​​catorView

如何在 UIAlertView 的中心添加 UIActivityIndi​​catorView?

为啥是UIActivityIndi​​catorView!展开时为零?

如何在 UICollectionViewCell 中将 UIActivityIndi​​catorView 居中?