这取决于您要返回的内容。但是你可能会感到困惑的是,如果你从 inDatabase 块内发出 return 语句,你是从块返回,而不是从包含这个 inDatabase 块的方法返回。
因此,您根本不从 inDatabase 块返回值,而是从块外部返回值。所以你通常会做的是,你会声明你的变量要在inDatabase块之外返回,你的inDatabase块会更新它,然后,当块完成时,那是您返回结果的时候(不是来自inDatabase 块)。
一个常见的例子是如果你正在构建一个NSMutableArray:所以在块之外创建可变数组,然后从块内添加值,然后返回结果之后你退出inDatabase 块:
NSMutableArray *results = [NSMutableArray array]; // declare this outside the block
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @(1)];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @(2)];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @(3)];
FMResultSet *rs = [db executeQuery:@"select * from foo"];
while ([rs next]) {
...
[results addObject:result]; // add values inside the block
}
[rs close];
}];
return results; // return the results outside the block
或者,如果您正在处理一些基本类型,例如 NSInteger 或 BOOL 或者您有什么,您可以使用 __block 限定符声明变量。例如,我将使用它来返回一个 BOOL 成功变量,例如:
__block BOOL success; // again, define outside the block
NSMutableArray *results = [NSMutableArray array];
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @(1)];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @(2)];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @(3)];
FMResultSet *rs = [db executeQuery:@"select * from foo"];
if (!rs)
{
NSLog(@"%s: %@", __FUNCTION__, [db lastErrorMessage]);
success = NO; // set the value inside the block
return; // note, this doesn't exit the method; this exits this `inDatabase` block
}
while ([rs next]) {
...
}
[rs close];
success = YES; // another example of setting that `success` variable
}];
// so whether I successfully completed the block, or whether I hit the `return`
// statement inside the block, I'll fall back here, at which point I'll return my
// boolean `success` variable
return success; // don't return the value until after you exit the block
虽然您第一次遇到它时可能会感到困惑,但理解这一点很有用。当你开始大量使用 GCD 块时,这种模式很常见。当您有一个块(由^ 字符表示)时,您几乎必须将其视为您在 inside 的 main 方法中定义的一个函数。当您在块内遇到return 时,您将返回到包含该块的方法。
方块介绍见: