我有这段代码:
- (NSString *) login {
datos=@"";
NSString __block *variable;
NSString *sqlQueryExisteUsuario;
sqlQueryExisteUsuario = [[NSString alloc] initWithFormat:@"SELECT COUNT(*) FROM tableName WHERE field='value' AND field='value'"];
SQLClient* client = [SQLClient sharedInstance];
client.delegate = self;
[client connect:@"serverName" username:@"username" password:@"password" database:@"database" completion:^(BOOL success) {
[client execute:sqlQueryExisteUsuario completion:^(NSArray* results) {
variable = [self processLogin:results];
NSLog(@"In: %@",variable);
[client disconnect];
}];
}];
NSLog(@"Out: %@",variable);
return nil;
}
- (NSString *)processLogin:(NSArray*)data
{
existeArray = [NSMutableArray array];
for (NSArray* table in data)
for (NSDictionary* row in table)
for (NSString* column in row)
[existeArray addObject:row[column]];
NSString *existe=existeArray[0];
if([existe isEqualToString:@"1"])
{
datos=@"yes";
}else{
datos=@"no";
}
return datos;
}
在NSLog
的第一次调用中,以In
开头,值显示。在以Out
开头的第二个调用中,该值未显示。为什么呢?
答案 0 :(得分:1)
您的connect
是异步方法,因此NSLog...
行将早于completion
阻止执行。所以,你还必须使用块:
- (NSString *) loginWithCompletion:(void(^)(NSString *result))handler
{
datos=@"";
NSString *sqlQueryExisteUsuario;
sqlQueryExisteUsuario = [[NSString alloc] initWithFormat:@"SELECT COUNT(*) FROM tableName WHERE field='value' AND field='value'"];
SQLClient* client = [SQLClient sharedInstance];
client.delegate = self;
[client connect:@"serverName" username:@"username" password:@"password" database:@"database" completion:^(BOOL success) {
if (success) {
[client execute:sqlQueryExisteUsuario completion:^(NSArray* results) {
NSString *variable = [self processLogin:results];
NSLog(@"In: %@",variable);
[client disconnect];
if (handler) {
handler (variable);
}
}];
} else {
//TODO: handle this
if (handler) {
handler (nil);
}
}
}];
}
用法:
- (void)ff
{
[self loginWithCompletion:^(NSString *variable) {
//Do something with variable
}];
}
答案 1 :(得分:0)
问题是你的变量是在一个完成块中设置的:variable
变量(不是一个好名字,BTW!)不仅设置在一个而是两个块内 - 这就是“完成”部分你的代码 - 两者都是最好的想法(!)就像一个微型匿名函数:在这种情况下,它们在系统准备就绪时运行,而不是直接运行。
iOS将开始执行您的connect
代码,然后跳至NSLog(@"Out: %@",variable)
,然后执行connect
的完成模块,进而启动更多代码(execute
),它有自己的完成块,最终被执行。正如@rmaddy在下面的评论中所说,技术名称是异步代码:块内的位不会立即执行,这样系统可以在等待任务完成时继续执行其他操作。
所以正在运行的订单是:
1)您声明variable
。
2)你的连接代码开始了。
3)variable
被打印出来。
4)连接完成。
5)您的execute
代码开始。
6)您的execute
代码完成。
7)variable
被设置为最终值。