我有这段代码:
- (NSString *)obtenerDatosUsuario
{
__block NSString *result=@"";
[self obtenerDatosUsuarioSQL:^(NSString *resultadoSQL){
result=resultadoSQL;
}];
return result;
}
我希望返回的内容为resultadoSQL
答案 0 :(得分:0)
如果我对你的方法-obtenerDatosUsuarioSQL:
内发生的事情的猜测是正确的(即,它在后台线程中执行冗长的操作,并将结果提供给传递的块参数),那么你的代码将在下面运行顺序:
-obtenerDatosUsuario
-obtenerDatosUsuarioSQL:
,传递完成处理程序阻止。return
末尾的-obtenerDatosUsuario
语句,然后退出方法正文。 返回的变量result
尚未设置! -obtenerDatosUsuario
。答案 1 :(得分:0)
有一些方法可以使这个异步方法同步运行(例如信号量),但它通常是一个非常非常糟糕的主意。最有可能的是,obtenerDatosUsuarioSQL
是异步的,因为有可能(即使只有很小的机会)结果不会立即返回。也许SQL可能会很慢。或者,您最终可能会从多个线程进行查询,因此此查询可能必须等待其他线程中的查询完成。或者可能还有其他原因。但无论什么原因,这种方法都是作为异步方法实现的,你应该接受它,而不是反对它。如果您将obtenerDatosUsuario
更改为同步返回,则可以解决各种可能的问题。
相反,您应该在代码中采用异步模式。例如,让我们假设您有一些代码计划将obtenerDatosUsuario
的结果用于其他目的,例如:
NSString *resultadoSQL = [self obtenerDatosUsuario];
// use `resultadoSQL` here
只需将其更改为:
[self obtenerDatosUsuarioSQL:^(NSString *resultadoSQL){
// use `resultadoSQL` here
}];
// but not here
而且,如果您在某种方法中使用obtenerDatosUsuarioSQL
,而您当前正试图立即返回该值,那么也要将其更改为异步行为。例如,让我们假设你有类似的东西:
- (NSString *)someOtherMethod {
NSString *resultadoSQL = [self obtenerDatosUsuario];
// let's assume you're doing something else with `resultadoSQL` to build some other string
NSString *string = ... // some expression using `resultadoSQL`
return string;
}
然后,您将其更改为也采用异步模式:
- (void)someOtherMethod:(void (^)(NSString *))completionHandler {
[self obtenerDatosUsuarioSQL:^(NSString *resultadoSQL){
NSString *string = ... // some expression using `resultadoSQL`
completionHandler(resultadoSQL);
}];
}
当你第一次遇到这个时,这看起来似乎不必要地复杂,但异步编程是如此关键,这是Cocoa编程的一个基本部分,人们必须熟悉这些常见的异步模式,比如块。就个人而言,我们在Xcode" Code Snippet Library"中使用了块语法,以至于我create code snippets。 for typical block patterns,它简化了生活,让你走出了记忆不直观的块语法的世界。
但是不要试图将异步方法包装在另一个使其同步运行的方法中。如果你这样做,你可以解决许多类型的问题。