我想从异步内部函数内部的外部函数返回。很快,我会为此目的使用完成处理程序,该处理程序会从函数中逸出。但是在Objective-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语句一样从函数返回。
更容易调用另一个告诉它已完成的函数。
-(void)chosenFrom:(NSDictionary<NSString *,id> *)info{
[self asyncCode:info withCompletion:^(NSData *imageData) {
if(imageData) {
[self completedAsync:imageData];
}
}];
}
-(void)completedAsync:(NSData*) imageData {
// do your thang.
}
似乎您以不同的方式问了同样的问题两次,人们一直在帮助您。这并不是一个真正的答案,因为我并不真正知道这个问题,但是希望这可以帮助您找到答案或提出不同的问题,以便人们可以为您提供帮助。
让我们从您的发言开始:
转义意味着从函数中返回,就像return语句一样
您已经在Swift中使用@escaping
进行了引用。尽管术语转义在某些语言中可能用来指代您所说的内容,但这根本不是Swift中的意思。
混淆它在Swift中的含义是合理的,因为它本质上使程序员可能/应该在该语言中看到隐藏的编译器优化。 Swift中的定义是:
闭包被称为转义函数,当闭包作为参数传递给函数时,但在函数返回后被调用。当您声明一个将闭包作为其参数之一的函数时,可以在参数的类型前写
@escaping
表示允许转义闭包。闭包可以逃脱的一种方法是将其存储在函数外部定义的变量中。例如,许多启动异步操作的函数都将闭包参数用作完成处理程序。该函数在开始操作后返回,但是直到操作完成后才调用闭包–闭包需要转义,稍后再调用。
Swift编程语言(Swift 4.2)
这是告诉您@escaping
影响闭包的存储和使用方式,而不影响闭包本身在调用时的实际作用。调用闭包时,无论是否将其标记为@escaping
,它都会执行相同的操作。
继续,用于说明@escaping
的示例与您所处的情况有关–您显然希望有一个方法,例如A,启动一个异步操作,例如* B **,并通过它是一个闭包,例如C,稍后调用该闭包将导致A返回。这是不可能的,因为当C被入侵时,没有调用A返回。再次查看示例,重点添加:
闭包可以逃脱的一种方法是将其存储在函数外部定义的变量中。例如,许多启动异步操作的函数都将闭包参数用作完成处理程序。 该函数在开始操作后返回,但是直到操作完成才调用闭包
A已启动B后,它返回,在调用C时,调用A的调用已启动B具有已经返回。您显然在要求不可能!
那么您打算做什么?
您的意图可能是使A及其开始的异步操作B显示为单个synchronous单元,并且A直到B才返回已经完成了工作。
在少数情况下,需要将异步性包装为同步操作,并且还有更多的情况,人们试图这样做以使异步性更易于处理,但最终却破坏了过程中异步性的所有好处。进行这种包装通常看起来很简单。但是,除非您对GCD块模型,信号量,线程,阻塞和死锁有所了解,否则它会为那些疏忽的人保留陷阱。如果您的意图太试图包装异步性,那么更好的方法是采用异步方式,在您的情况下,应弄清楚如何使闭包 C asynchronous 异步性