NSURLSession.sharedSession().dataTaskWithRequest 运行缓慢

Posted

技术标签:

【中文标题】NSURLSession.sharedSession().dataTaskWithRequest 运行缓慢【英文标题】:NSURLSession.sharedSession().dataTaskWithRequest runs slow in function 【发布时间】:2016-05-18 18:47:34 【问题描述】:

当我想将 mysql 数据库中的数据填充到类对象中时,我的问题就出现了。我试图返回一个对象数组,它返回nil,然后它以某种方式填充自己。在返回空白数组之前如何使其填充?

这是我的代码和代码输出的截图

import Foundation

class Research

  var mainResearchImageURL:String = ""
  var userProfileImageURL:String = ""
  var caption:String = ""
  var shortDescription:String = ""

  init(mainResearchImageURL :String, userProfileImageURL:String, caption:String, shortDescription:String)
  

    self.mainResearchImageURL = mainResearchImageURL
    self.userProfileImageURL = userProfileImageURL
    self.caption = caption
    self.shortDescription = shortDescription
   

  class func downloadAllResearches()->[Research]
  
    var researches = [Research]()
    let urlString = "http://localhost/test/index.php"
    let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
    request.HTTPMethod = "POST"
    let postString = "action=listresearches"
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: data, response, error in
        if (error == nil) 

            do 
                let json =  try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSArray
                //let dictionary = json!.firstObject as? NSDictionary

                var counter:Int = 0;
                for line in json!
                    let researchData = line as! NSDictionary
                    let researchLineFromData = Research(mainResearchImageURL: researchData["research_mainImageURL"] as! String, userProfileImageURL: researchData["research_creatorProfileImageURL"] as! String, caption: researchData["research_caption"] as! String, shortDescription: researchData["research_shortDescription"] as! String)
                   researches.append(researchLineFromData) //researches bir dizi ve elemanları Research türünde bir sınıftan oluşuyor.

                    counter += 1
                    print ("counter value \(counter)")
                    print("array count in loop is = \(researches.count)")
                
            catch let error as NSError
                print(error)
            
         else 
            print(error)
        )
    task.resume()

    print("array count in return is = \(researches.count)")
    return researches
  

这是输出:

【问题讨论】:

您遇到的问题不是“问题”。 Swift 通过在后台执行任何 Web 请求而不是在它完成时阻止您的应用程序来帮您一个忙。你只需要相应地处理它。我会调查调度组。一旦任务完成,它们将允许您执行代码。在这里检查这个答案:***.com/questions/35906568/… 【参考方案1】:

在你的completionHandler上添加这个(如果你更新一个视图它会起作用)

dispatch_async(dispatch_get_main_queue(), 
    if (error == nil)  ...... 
)

建议 1:

返回任务并在您的方法中使用完成参数, 如果任务太慢,您可以取消任务。

建议 2: 使用 alamofire 和 swiftyJson 框架

【讨论】:

【参考方案2】:

这里发生的是你在完成之前返回值(记住调用是异步的),你可以这样做:

class func downloadAllResearches(success:([Research])->Void,failure:(String)->Void)

    var researches = [Research]()
    let urlString = "http://localhost/test/index.php"
    let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
    request.HTTPMethod = "POST"
    let postString = "action=listresearches"
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: data, response, error in
    if (error == nil) 

        do 
            let json =  try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSArray
            //let dictionary = json!.firstObject as? NSDictionary

            var counter:Int = 0;
            for line in json!
                let researchData = line as! NSDictionary
                let researchLineFromData = Research(mainResearchImageURL: researchData["research_mainImageURL"] as! String, userProfileImageURL: researchData["research_creatorProfileImageURL"] as! String, caption: researchData["research_caption"] as! String, shortDescription: researchData["research_shortDescription"] as! String)
               researches.append(researchLineFromData) //researches bir dizi ve elemanları Research türünde bir sınıftan oluşuyor.

                counter += 1
                print ("counter value \(counter)")
                print("array count in loop is = \(researches.count)")
            
            success(researches)
        catch let error as NSError
            print(error)
            failure("Can be extract from NSERROR")
        
     else 
        print(error)
        failure("Error - Can be extract for NSERROR")
    )
task.resume()

为了调用这个函数,使用这样的东西:

    Research.downloadAllResearches( (objects:[Research]) -> Void in
        dispatch_async(dispatch_get_main_queue(),  () -> Void in
            //Do whatever you like with the content
        )
    )  (failureLiteral:String) -> Void in

    

【讨论】:

对我不起作用。当我尝试像你一样调用函数时,Xcode 会用红旗警告我并说“预期声明”。 你能拍个打印屏幕吗?嗯,你把最后一个 放在方法中了吗(downloadAllResearches),我不小心漏掉了(在块代码中)

以上是关于NSURLSession.sharedSession().dataTaskWithRequest 运行缓慢的主要内容,如果未能解决你的问题,请参考以下文章