Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 从完成处理程序返回值_Swift - Fatal编程技术网

Swift 从完成处理程序返回值

Swift 从完成处理程序返回值,swift,Swift,我想从api调用返回值 调用我的api类(我想获取res中的值): api类: import Foundation class Api_test { func getAllStations(completionHandler: (response : XMLIndexer) -> ()) { getRequest { result in completionHandler(response: SWXMLHash.parse(result))

我想从api调用返回值

调用我的api类(我想获取res中的值):

api类:

import Foundation

class Api_test {

     func getAllStations(completionHandler: (response : XMLIndexer) -> ()) {

    getRequest { result in
        completionHandler(response: SWXMLHash.parse(result))
    };
}

    func getRequest(completionHandler: (result: NSData) -> ()) {
        let baseUrl = "http://api.test.com"
        let request = NSMutableURLRequest(URL: NSURL(string: baseUrl)!)
        let session = NSURLSession.sharedSession()
        request.HTTPMethod = "GET"

        let task = session.dataTaskWithRequest(request) {
            (data, response, error) in

            if data == nil {
                print("dataTaskWithRequest error: \(error)")
                return
            } else {
                completionHandler(result: data!)
            }
        }
        task.resume()
    }
}

一切都按预期进行,但我仍停留在将值返回给getSomething函数这一点上。数据是xml格式的。如何将结果集作为res(viewDidLoad)中的返回值获取?

NSURLSession
是一个完全异步的网络API,因此理想情况下,视图控制器应该正确运行,而不是等待数据从网络返回

这里有三个选项:

  • 您可以将完成块传递给
    getSomething
    ,并让它将结果传递给块:

    func getSomething(completionHandler: (result: XMLIndexer) -> ()) {
      getRequest { result in
        completionHandler(result: SWXMLHash.parse(result))
      }
    }
    
    override func viewDidLoad() {
      ...
      t.getSomething { res in
        print(res)
      }
    }
    
  • 如果在视图显示在屏幕上之前迫切需要手头的XML数据,可以让主线程等待网络操作完成。您可以使用:

  • 最后一个选项是,您可以使用另一个同步解析的第三方。有一个很棒的名字叫:


  • 是否要使整个程序等待从
    getRequest
    函数获得响应?将完成闭包传递给
    getSomething
    ?然后可以在
    getResult
    的完成处理程序中调用它。@ozgur是,因为程序需要数据。或者我应该在另一个线程上运行整个类?@originaluser2如何执行该操作?@da1lbi3让您的
    getSomething
    执行
    (whateverTypeYourDataIs)->()
    闭包,并从
    getRequest
    完成闭包中调用它。与您使用
    getRequest
    执行的操作完全相同。作为一般规则,您不应该让您的程序等待某些东西,除非它真的必须等待,即使如此,它也不应该在主线程上等待。虽然根据你告诉我们的情况很难给出建议,但你能提供一点关于你在这里实际要做什么的背景吗?我完全同意这个答案。。。方法2除外。你真的不应该在主线程上等待。从编程和用户体验的角度来看,这都不是一个好主意。我强烈建议只做一个异步请求,并在加载时向用户显示一条加载消息(可以在视图上显示)。这样用户就不会惊慌失措,认为应用程序只是冻结了。我知道,这就是为什么我说理想情况下视图控制器应该正确运行,直到数据从网络返回。我只是告诉他有办法,而不是告诉他应该这么做。啊,好吧,略过你的第一段,我的错!尽管现在确实在考虑它,
    dispatch\u sync
    无论如何都不会等待请求完成,因为
    getResult
    方法本身是异步的。你必须使用信号灯,尽管同样的健康警告仍然适用。是的,你完全正确。我将相应地更新我的代码。我完全忽略了一个事实,即getRequest将立即在分派块中返回。那里需要信号量或调度组。谢谢你发现了!
    func getSomething(completionHandler: (result: XMLIndexer) -> ()) {
      getRequest { result in
        completionHandler(result: SWXMLHash.parse(result))
      }
    }
    
    override func viewDidLoad() {
      ...
      t.getSomething { res in
        print(res)
      }
    }
    
    func getSomething() -> XMLIndexer? {
      var xml: XMLIndexer? = nil
      let semaphore: dispatch_semaphore_t = dispatch_semaphore_create(0)
      getRequest { result in
        xml = SWXMLHash.parse(result)
        dispatch_semaphore_signal(semaphore)
      }
      dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
      return xml
    }
    
    var error: NSError?
    let xml = ONOXMLDocument(data: result, error: &error)