我在iOS应用程序中使用FMDatabaseQueue
。我一直在理解如何在创建队列时返回值。感谢您的帮助!!
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];
FMResultSet *rs = [db executeQuery:@"select * from foo"];
while ([rs next]) {
...
}
// I want value to be returned from here
}];
答案 0 :(得分:15)
这取决于你想要回归的东西。但令你困惑的是,如果你从return
块中发出inDatabase
语句,那么你将从块返回,而不是从包含此{{1}的方法返回阻止。
因此,您只是不返回inDatabase
块中的值,而是返回块外部的值。那么你通常会做的是,你将声明你的变量在<{em>} 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
限定符声明该变量。例如,我将使用它来返回BOOL成功变量,例如:
__block
虽然第一次遇到它时可能会让人感到困惑,但理解这一点很有用。当你开始大量使用GCD时,这种模式很常见。当你有一个块(由__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
字符表示)时,你几乎不得不把它想象成你在主方法中定义 的函数。当您在块中遇到^
时,您将返回包含该块的方法。
有关块的介绍,请参阅:
答案 1 :(得分:0)
您可以使用块方法传递其他内容,如下例所示
如果您阅读FMDB's Github Page页面,则可能了解其运作方式
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];
if (whoopsSomethingWrongHappened) {
*rollback = YES;
return;
}
// etc…
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];
}];
FMDatabaseQueue will run the blocks on a serialized queue
(hence the name of the class). So if you call FMDatabaseQueue's
methods from multiple threads at the same time, they
will be executed in the order they are received.
This way queries and updates won't step on each other's toes,
and every one is happy.
Note: The calls to FMDatabaseQueue's methods are blocking. So even though you are passing along blocks, they will not be run on another thread.