我想从异步内部函数内部的外部函数返回。 很快,我会为此目的使用完成处理程序,该处理程序会从函数中逸出。但是在目标c中,完成处理程序实际上不会从函数中返回:
我的功能如下:
-(void)chosenFrom:(NSDictionary<NSString *,id> *)info{
[self asyncCode:info withCompletion:^(NSData *imageData) {
if(imageData) {
// I want to return from chosenFrom function ***inside here.***
}
}];
// This is to illustrate completion handler don't escape
[self checkCompletionEscaping:^(NSString * lad) {
NSLog(@"Check me %@", lad);// It would print all 3 lines below.
}];
}
-(void) checkCompletionEscaping:(void(^)(NSString * lad)) completion {
completion(@"Hello"); // completion handler should've escaped from func.
completion(@"Shivam");
completion(@"How are you");
}
如果我要使用swift,我可以使用完成处理程序轻松地从内部函数内部的外部函数返回:
private func getHistoryKeys(searchterm: String, completion: @escaping () -> ()) {
let url = PubmedAPI.createEsearchURL(searchString: searchterm)
let task = session.dataTask(with: url) { (data, response, error) in
if let error = error {
completion() // This would work as return
} else {
completion() // Same as return
}
}
task.resume()
}
PS:转义意味着像return语句一样从函数中返回。
答案 0 :(得分:0)
更简单的是调用另一个告诉它已完成的函数。
-(void)chosenFrom:(NSDictionary<NSString *,id> *)info{
[self asyncCode:info withCompletion:^(NSData *imageData) {
if(imageData) {
[self completedAsync:imageData];
}
}];
}
-(void)completedAsync:(NSData*) imageData {
// do your thang.
}
答案 1 :(得分:0)
您似乎已经以不同的方式问了同样的问题两次,人们一直在帮助您。这并不是一个答案,因为我并不真正知道这个问题,但是希望这可以帮助您找到答案或提出不同的问题,以便人们可以为您提供帮助。
让我们从您的陈述开始:
转义意味着像return语句一样从函数中返回
,您已经在Swift中提到使用@escaping
。虽然转义一词在某种语言中可能用来指代您所说的,但这根本不是Swift中的意思。
对它在Swift中的含义感到困惑是合理的,因为它实质上使程序员可能/应该用该语言看到隐藏的编译器优化。 Swift中的定义是:
当将闭包作为参数传递给函数时,闭包被称为转义一个函数,但在函数返回后被调用。声明一个将闭包作为其参数之一的函数时,可以在参数的类型前写
@escaping
,以指示允许转义闭包。闭包可以逃脱的一种方法是将其存储在函数外部定义的变量中。例如,许多启动异步操作的函数都将闭包参数用作完成处理程序。该函数在开始操作后返回,但是直到操作完成后才调用闭包–闭包需要转义,稍后再调用。
Swift编程语言(Swift 4.2)
这告诉您@escaping
影响闭包的存储和使用方式,而不影响闭包本身在调用时的实际作用。不论闭包是否标记为@escaping
,调用闭包都会执行相同的操作。
继续,用于说明@escaping
的示例与您所处的情况有关–您显然希望有一个方法,例如 A ,启动一个异步操作,例如* B **,将其传递给闭包,例如 C ,稍后调用该闭包将导致 A 返回。这是不可能的,因为 C 被入侵时,没有 A 的调用要返回。再次查看示例,重点添加:
闭包可以逃脱的一种方法是将其存储在函数外部定义的变量中。例如,许多启动异步操作的函数都将闭包参数用作完成处理程序。 函数在开始操作后返回,但是直到操作完成才调用闭包
A 启动 B 后,它会返回,直到调用 C 时调用以 B 开头的> A 已已返回。您显然是在要求不可能!
那你想做什么?
您的意图可能是使 A 及其开始于 B 的异步操作显示为单个 synchronous 单元,对于 A 在 B 完成工作之前不返回。
在许多情况下,由于需要同步操作而包装了异步性,因此还有很多情况,人们试图这样做以使异步性更易于处理,但最终却破坏了异步性的所有好处。过程。进行这种包装通常看起来很简单。但是除非您对 GCD块模型,信号量,线程,阻止和死锁,它为陷入困境的人提供陷阱。
如果您的意图太过尝试包装异步性,那么更好的方法是采用异步性,在您的情况下,请弄清楚如何使闭包 C 达到被异步调用更长时所需的功能在您的方法 A 的相应调用终止并且不再存在之后。三十年前,异步是日常编程的深奥终结,而今天,它已成为其核心,您需要了解和使用它。
如果尝试拥抱异步之后,您确定自己有一种罕见的情况需要隐藏在同步包装中,请在SO上搜索异步,信号量等,您应该找到解决方案。
如果您陷入了异步性的境地,或者实际上是在问完全不同的事情,请提出一个新问题,表明您已做/尝试过的事情,等等,无疑会有人帮助您接受下一步。
HTH