这取决于您要返回的内容。但是你可能会感到困惑的是,如果你return
从块内部发出一个语句inDatabase
,你是从块返回的,你不是从包含这个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
或者,如果您正在处理一些基本类型,例如 a NSInteger
orBOOL
或您有什么,您将使用__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 块时,这种模式很常见。当您有一个块(由^
字符表示)时,您几乎必须将其视为您在 main 方法中定义的函数。当您遇到return
块内部时,您将返回到包含该块的方法。
有关块的介绍,请参见: