views:

842

answers:

3

I wonder how run sqlite querys in the background as suggested in http://stackoverflow.com/questions/155964/what-are-best-practices-that-you-use-when-writing-objective-c-and-cocoa

This is my try:

- (void) run:(NSString *)sql {
NSArray *data = [NSArray arrayWithObjects:
     sql,
     [self returnItemClass],
     nil];

NSInvocationOperation *operation = 
[[NSInvocationOperation alloc] initWithTarget:self 
          selector:@selector(loadRecords:) 
            object:data]; 
[self.queue addOperation:operation];
[operation release];
}

- (void) loadRecords:(NSArray *)data {
    NSLog(@"Runing sql");
    NSString * sql = [data objectAtIndex:0];
    Class cls = [data objectAtIndex:1];

    Db *db= [Db currentDb];

    NSArray *list = [db loadAndFill:sql theClass:cls];
    [UIAppDelegate performSelectorOnMainThread:@selector(recordsLoaded:)
                                           withObject:list
                                        waitUntilDone:YES];
}

- (void) recordsLoaded:(NSArray *)data {
NSLog(@"Loading sql");
for (DbObject *o in data) {
 [self.objectCache setObject:o forKey:[NSNumber numberWithInt:o.Id]];
}
}

However, I get a error when try to run

    [UIAppDelegate performSelectorOnMainThread:@selector(recordsLoaded:)
                                       withObject:list
                                    waitUntilDone:YES];

And complain about not can send a message to recordsLoaded.

This is the correct aproach?

And how fill the data in the UITableView?

A: 

The problem there is that the iPhone really doesn't have a way to readily run programs in the background.

Charlie Martin
I know about background process. I'm talking about multi-threading here..
mamcx
Then maybe you shouldn't have *said* background processes, eh?
Charlie Martin
dunno why you got downvoted. +1
Randolpho
+1  A: 

There isn't too much in the way of multi-threading iPhone applications, as a result of Apple's wishes and design.

The generic messaging philosophy, however, is conducive to writing event-oriented programs. Your program should aim to respond to user input and environmental variables by setting the delegates to event dispatchers.

SQLite3, as a database, is not a server in the classical sense. Its protocol for interacting with a specific file format, whose libraries can be directly included in source code. In other words, when you need to get data from the database, you should be able to read it immediately. You shouldn't, and can't, spawn a SQLite3 process to work in the background.

Regarding your stated syntax, why are you using performSelectorOnMainThread... instead of just calling

[UIAppDelegate recordsLoaded:list]

?

Willi Ballenthin
Because that is what I found in examples of this...
mamcx
Presumably that's because the recordsLoaded: method updates the UI, and you should only update the UI from the main thread. Since this code is going to be running on a background thread, you need to use performSelectorOnMainThread.
Daniel Dickison
A: 
[UIAppDelegate performSelectorOnMainThread:@selector(recordsLoaded:)
                                withObject:list
                             waitUntilDone:YES];

should be

[self performSelectorOnMainThread:@selector(recordsLoaded:)
                       withObject:list
                    waitUntilDone:YES];

unless you've defined UIAppDelegate as something like

#define UIAppDelegate ([UIApplication sharedApplication].delegate)
Daniel Dickison
Yes, I do that...
mamcx