I've really been trying, but I am just not getting blocks very well. I am in the process of using the FMDatabaseQueue, and I am trying to make a very simple queue based query. This is what I have:
-(NSString *) getReferenceForPage:(NSInteger) page
{
[queue inDatabase:^(FMDatabase *db) {
FMResultSet *rs = [db executeQuery:@"SELECT ref_text FROM table WHERE page = ?",[NSNumber numberWithInteger:page]];
if ([rs next]) {
//this is where I get the string
}
}];
return @""; //And this is where I need to return it, but I can't get it to work
}
I don't know why this is so hard for me to grasp, but I need to be able to do something with the string that I am getting from the result set. Ordinarily, I would just return it, but that won't fly here. Can someone shed some light on this?
Thanks
EDIT: I am making calls to my db accessing object in hopes to return a specific value. A lot of these calls will be run on background threads, so I am using this database queue to be thread safe. I have updated the context surrounding the sql query to show what I am needing to do.
It seems your question boils down to "how do I return a value from inside a block back to the calling function?" It's actually rather simple, as long as the block is executed synchronously. Just use a __block
variable and assign to it.
__block NSString *result = nil;
[queue inDatabase:^(FMDatabase *db) {
// I'm assuming this is synchronous, because I'm not familiar with the API
FMResultSet *rs = [db executeQuery:@"SELECT ref_text FROM table WHERE page = ?", [NSNumber numberWithInteger:page]];
if ([rs next]) {
result = [[rs acquireStringSomehow] retain];
}
}];
return [result autorelease];
Note, the retain is because there may be an autorelease pool wrapped around the block and we need to make sure the value persists (and then we can autorelease it outside of the block).
If the block is executed asynchronously instead, then you can't possibly have the value get returned from the calling function. If you need to handle that case, then you need to hand the value back to the appropriate thread for later processing, e.g.
NSString *str = [rs fetchStringSomehow];
dispatch_async(dispatch_get_main_queue(), ^{
processString(str);
});