我在我的swift项目中使用了在objective-c中编写的基于nsurlssesion的包装器class。 Everthing正在发挥作用,除非我无法解决关闭如何在swift中工作。
在我的swift viewcontroller中:
DownloadManager().downloadFile(forURL: url, progressBlock: { (progress) -> () in
print("current progress is \(progress)")
}, completionBlock: { (completion) in
print("is completed : \(completion)")
}, enableBackgroundMode: false)
在我的Downloadmanager类(基于objc)中,无论何时调用nsurlssession委托,都会发生这种情况:
dispatch_async(dispatch_get_main_queue(), ^(void) {
if(download.progressBlock){
download.progressBlock(progress); //exception when progressblock is nil
}
});
下载对象有一个名为progressBlock的块类型属性:
typedef void(^TWRDownloadProgressBlock)(CGFloat progress);
输出:
current progress is 0.0908259372799894
current progress is 0.272477811839968
current progress is 0.363303749119957
current progress is 0.454129686399947
current progress is 0.544955623679936
current progress is 0.635781560959925
current progress is 0.726607498239915
current progress is 0.817433435519904
current progress is 1.0
代码流程:
问题: 第3点是如何发生的?
这是关闭在swift中表现的标准方式吗?具体来说,我想知道每次Dowload对象更改时是否自动调用闭包?
答案 0 :(得分:1)
闭包是自包含的功能块,可以在代码中传递和使用。 Swift中的闭包类似于C和Objective-C中的块以及其他编程语言中的lambdas。
闭包可以从定义它们的上下文中捕获和存储对任何常量和变量的引用。
在这种情况下,闭包在视图控制器中定义,然后传递 周围和后来打电话。
流程如下:
downloadFile
方法。progressBlock: ((CGFloat) -> Swift.Void)
闭包(它将CGFloat作为参数并且不返回任何内容)。download.progressBlock(progress)
,它只是从#2调用闭包并将CGFloat值作为参数传递。这是一个快速的游乐场示例:
import Foundation
import PlaygroundSupport
import TWRDownloadManager
PlaygroundPage.current.needsIndefiniteExecution = true
let downloadManager = TWRDownloadManager()
let url = "http://download.thinkbroadband.com/200MB.zip"
let progressClosure: (CGFloat) -> () = { (progress) in
print("current progress is \(progress)")
}
let completionClosure: (Bool) -> () = { (completion) in
print("is completed : \(completion)")
}
downloadManager.downloadFile(
forURL: url,
progressBlock: progressClosure,
completionBlock: completionClosure,
enableBackgroundMode: false
)