iOS How to read SQLite data in child thread

Narendar Singh

macrumors member
Original poster
Jun 22, 2012
76
0
INDIA
I have few hundredths of rows in my few tables. If I read these rows from main thread UI goes unresponsive.

I want to read these rows in some other thread so that my UI thread wont get stuck
(seems in iOS it is related to dispatch queue kind of thing, dont know very much)

I have written few code based on my understanding but my application is getting crash.

// This is my .h file

Code:
@interface HistoryViewController : UIViewController
{
    NSArray *data1; 
    NSArray *data2;
    NSArray *data3;
}

@property (nonatomic, retain) NSArray *data1; 
@property (nonatomic, retain) NSArray *data2;
@property (nonatomic, retain) NSArray *data3;
Code:
// This is my .m file

@synthesize data1, data2, data3;

- (void)readLocalDBData
{
    // start the activity indicator
    [self.view addSubview:fadeView];
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        DebugLog(@"STARTED LONG RUNNING TASK FROM HERE... "); 

        _data1  = [GetAppDelegate().databaseWrapper getDataFromTable1]; // returns nil in case of zero rows
        _data2  = [GetAppDelegate().databaseWrapper getDataFromTable2]; // returns nil in case of zero rows
        _data3  = [GetAppDelegate().databaseWrapper getDataFromTable3]; // returns nil in case of zero rows

        dispatch_async(dispatch_get_main_queue(), ^{
           
             DebugLog(@"FINISHED MY LONG RUNNING TASK...");
           
            // stop activity indicator
            [self.fadeView removeFromSuperview];

            // update ui method called
            [self updateUI];
        });
    });
}    

- (void)updateUI
{
    
    if (data1 == nil) 
    {
        [self.fadeView removeFromSuperview];
        return;
    }

[COLOR="Red"][B]   // in this line I am getting crash with EXE_BAD_ACCESS    
    DebugLog(@"History Items %@", [data1 count]);[/B][/COLOR]

    DebugLog(@"NEWS History Items %d",  [data2 count]);

    DebugLog(@"PRODUCT History Items %d", [data3 count]);

}
 

jnoxx

macrumors 65816
Dec 29, 2010
1,343
0
Aartselaar // Antwerp // Belgium
First of all, no need to create local ivar's AND property's
you can @synthesize data1 = _data1; and this will also create an ivar object for you.. :)
I don't understand why you make a difference between self.object and _object & object, you don't really know what to call when do you? (no offense, just asking).
And you say you get an error on an Bad EXCESS, which generally means you have an memory issue, are you using ARC or not?

Also, getting your data from the APpDelegate is really bad, and why do you use the ()? it's not really Java or C# or whatever here :p
And also in the updateUI, is your actual data1 setted or not?
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
If you access a sqlite db from more than one thread you need to get a database handle in each thread. Do not use the same database handle from more than one thread.

Don't access ivars directly (like _data = blah). Only use the @property. (like self.data = blah blah).

Don't access the UI from a background thread.

You should probably not use GCD. It is a low-level C API and a little complicated. Use NSOperation.
 

Narendar Singh

macrumors member
Original poster
Jun 22, 2012
76
0
INDIA
First of all, no need to create local ivar's AND property's
you can @synthesize data1 = _data1; and this will also create an ivar object for you.. :)
I don't understand why you make a difference between self.object and _object & object, you don't really know what to call when do you? (no offense, just asking).
Mistake from my side,
Code:
_data1  = [GetAppDelegate().databaseWrapper getDataFromTable1]; // returns nil in case of zero rows
_data2  = [GetAppDelegate().databaseWrapper getDataFromTable2]; // returns nil in case of zero rows
_data3  = [GetAppDelegate().databaseWrapper getDataFromTable3]; // returns nil in case of zero rows
it was actually
Code:
data1  = [GetAppDelegate().databaseWrapper getDataFromTable1]; // returns nil in case of zero rows
data2  = [GetAppDelegate().databaseWrapper getDataFromTable2]; // returns nil in case of zero rows
data3  = [GetAppDelegate().databaseWrapper getDataFromTable3]; // returns nil in case of zero rows
And you say you get an error on an Bad EXCESS, which generally means you have an memory issue, are you using ARC or not?
No, how to use that?

Also, getting your data from the APpDelegate is really bad, and why do you use the ()? it's not really Java or C# or whatever here :p
I have a helper class in which I have created C style function which return application delegate object. Do you feel it is wrong way? Please confirm.
Code:
AppDelegate* GetAppDelegate()
{
	return (AppDelegate*)[[UIApplication sharedApplication] delegate];
}
And also in the updateUI, is your actual data1 setted or not?
It may nil or some values based on this following call:
Code:
data1  = [GetAppDelegate().databaseWrapper getDataFromTable1]; // returns nil in case of zero rows
 
Last edited by a moderator:

Similar threads

  • MacCheetah3
9
Replies
9
Views
389
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.