标签: completionhandler

Swift:阻塞mainThread,直到函数用completionHandler加载数据/ NSURLSession

我想创建一个从url加载数据然后将responseData作为NSData返回的函数.我想阻止mainThread直到数据完成.这是我到目前为止:

功能:

typealias CompletionBlock = (NSData!, NSURLResponse!, NSError!) -> NSData
func requestURL(targetUrl: String, httpMethod: String, httpBody: String, completion: CompletionBlock){

// REQUEST
let target = NSURL(string: targetUrl) // URL
let request = NSMutableURLRequest(URL: target!) // REQUEST

// HTTP-METHOD
var method = httpMethod
if method != "POST" { method = "GET" } // STANDARD: GET
    request.HTTPMethod = method

// HTTP-BODY
let body = httpBody
if body != "" {
    request.HTTPBody = body.dataUsingEncoding(NSUTF8StringEncoding)
}

// NSURLSession
let session = NSURLSession.sharedSession()
let task = …
Run Code Online (Sandbox Code Playgroud)

completionhandler nsurlsession swift

0
推荐指数
1
解决办法
1235
查看次数

如何在 Swift 中使用完成处理程序链接函数?

我将一些函数链接在一起,一旦所有函数都运行完毕,我无法弄清楚如何使用返回值调用完成处理程序。

func getAirQuality(completion: (aqi: Int?) -> Void) {
    callAPI()
}

private func callAPI() {
    // ... get data
    self.parseDataForAQI(data: data)
}

private func parseDataForAQI(data: Data) {
    let aqi = aqi
    // Send aqi up to completion handler in getAirQuality
}
Run Code Online (Sandbox Code Playgroud)

所以当一切都说完后,我可以做这样的事情:

getAirQuality(completion: { aqi -> Void in {
    // Do something with aqi
})
Run Code Online (Sandbox Code Playgroud)

chaining completionhandler swift

0
推荐指数
1
解决办法
864
查看次数

如何在Swift中创建一个可选的完成处理程序?

当前,我有一个完成处理程序:

open func Start(completion: (() -> Void)) { ... }
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,我必须始终致电completion。我怎样才能使它成为可选的,所以在某些方法中我将使用completion块,而在另一些方法中,我将跳过它们而不添加到我的方法调用中?

例如,我想要与以下内容相同:

self.present(<#T##viewControllerToPresent: UIViewController##UIViewController#>, animated: <#T##Bool#>, completion: <#T##(() -> Void)?##(() -> Void)?##() -> Void#>)
Run Code Online (Sandbox Code Playgroud)

我试过了

open func Start(completion: (() -> Void)? = nil) { ... }
Run Code Online (Sandbox Code Playgroud)

添加问号,但是在这种情况下,我必须调用可选的完成块

completion?()
Run Code Online (Sandbox Code Playgroud)

我不能简单地打电话

start()
Run Code Online (Sandbox Code Playgroud)

我不需要在完成块中。需要我叫它

completionhandler swift

0
推荐指数
1
解决办法
208
查看次数

完成处理程序被调用两次(使用线程)

我目前正在 Xcode 10 Playground (Swift 5) 中测试此代码:

func one() {
    let test = "bla"
    two(test, completion: { (returned) in
        print(returned)
        })
}

func two(_ test: String, completion: @escaping (_ returned: String?) -> Void) {
    DispatchQueue.global(qos:.background).async {
        if !test.isEmpty {
            //Some slow stuff
            DispatchQueue.main.async {
                return completion("hi!")

            }
        }

        //Also some slow stuff
        DispatchQueue.main.async {
            return completion(nil) //can't have this in "else"!
        }
    }
}

one()
Run Code Online (Sandbox Code Playgroud)

问题是“hi”和“nil”都被打印了。

如果我摆脱线程,它工作得很好,但有了它,它似乎在DispatchQueue.main.async第一个线程有机会返回之前到达第二个线程。

在我的实际代码中的“一些缓慢的东西”中还有很多事情发生,if但我不能依赖在调用第二次返回之前花费足够长的时间来返回。

如何实现这一点:让函数在后台线程中运行,但在主线程上仅返回一次(就像通常没有线程的代码一样)?

ios completionhandler swift ios-multithreading dispatch-queue

0
推荐指数
1
解决办法
3874
查看次数

在 iOS Swift 中实现方法时如何为闭包命名(语法问题)

我创建了下面这两种方法来注销用户。当 logout2(...) 被调用时,用户可以在 logout1() 运行之前在 anyFinalChanges 中进行任何更改。

  private func logout1() {
    Cache.clearCache()
  }
  
  func logout2(anyFinalChanges: () -> (), userLoggedOut: () -> ()) {
    anyFinalChangesInThisClosure()
    logout()
    userLoggedOut()
  }
Run Code Online (Sandbox Code Playgroud)

当我实现注销方法时,第二个闭包不显示名称

  .logOut2(anyFinalChanges: {

  }) { //No Name here.. why is that?

  }
Run Code Online (Sandbox Code Playgroud)

我怎样才能使闭包的名称始终出现?

closures ios completionhandler swift

0
推荐指数
1
解决办法
1069
查看次数