我正在努力尝试使用Swift创建一个用于我自己的教育目的的应用程序。
现在,我具有以下(期望的)执行顺序:
我最苦恼的问题是要知道闭包之后的代码是在闭包结束之后(同步)执行还是在闭包执行之前或同时执行。
例如:
FirstViewController
var response: [DDGCharacter]
//coreData is an instance of such class
coreData.load(onFinish: { response in //Custom method in another class
print("Finished loading")
self.response = response
})
print("Executed after loading data from Core Data")
//If no data is saved, download from API
if response.count == 0 {
//Download from API
}
我已经完成了上述测试,并在10次运行中得到了相同的结果:
Finished loading
Executed after loading data from Core Data
在全部10个实例中,但这可能是因为负载没有花费太多时间来完成,因此似乎不是同步的。
所以我的问题是,是否将始终以该顺序执行该命令而与数据量无关?还是可能改变?我也做了一些调试,并且它们都在主线程上执行。我只想确保我的假设是正确的。
根据注释的要求,这是在load()
方法中完成的实现:
func load(onFinish: ([DDGCharacter]) -> ()) {
var characters: [DDGCharacter] = []
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject> (entityName: "DDGCharacter")
do {
characters = try managedContext.fetch(fetchRequest) as! [DDGCharacter]
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
onFinish(characters)
}
答案 0 :(得分:1)
您对load(onFinish:)
的实现非常令人惊讶并且过于复杂。幸运的是,这有助于证明您要问的问题。
闭包在有人调用时执行。因此,在您的情况下,onFinish
在方法的末尾被调用,这使它成为同步的。成为“闭包”并不会使任何事情异步。它与调用函数相同。多次调用闭包是完全正常的(例如,map
会这样做)。否则可能永远不会被调用。或者它可能被异步调用。从根本上讲,这就像传递一个函数。
当我说“它与匿名函数稍有不同”时,我指的是“关闭”的“关闭”部分。封闭“封闭”了当前环境。这意味着它将捕获闭包内部引用的局部范围内的变量。这与函数略有不同(尽管它比语法更重要的是语法,实际上在某些情况下函数可能会成为闭包)。
在这种情况下,更好的实现只是返回数组。