I wrote a custom “JSON fetcher”. From my view controller I call [loader start]; and when loader is done, it runs the delegate method [self.delegate doneLoading];.
This all works, however the UI is blocked — can’t move anything — until the loader is done. I thought that if I did the loading over my own delegate method, this wouldn’t happen. What am I missing here? Is there some extra method I need to call?
- (void)getBandArray
{
if (![self localBandVersion] || [self remoteBandVersion] > [self localBandVersion] || !CACHING) {
NSLog(@"Band array loaded remotely.");
[self startLoadingBands];
}else{
NSLog(@"Band array loaded from disk.");
[self loadBandsFromDisk];
}
}
startLoadingBands starts the NSURLConnection, loadBandsFromDisk looks like this:
- (void)loadBandsFromDisk
{
NSData *dataFromDisk = [NSData dataWithContentsOfFile:[self fileStringForTag:JNKBandTag]];
if (dataFromDisk) {
NSLog(@"Found band cache on disk...");
NSString *strToParse = [[NSString alloc] initWithData:dataFromDisk encoding:NSUTF8StringEncoding];
SBJsonParser *jsonObject = [[SBJsonParser alloc] init];
NSError *jsonError;
NSArray *parsedResult = [jsonObject objectWithString:strToParse error:&jsonError];
[strToParse release];
[jsonObject release];
if (parsedResult && [parsedResult count] > 0) {
NSLog(@"Parsed bands, handing over to delegate...");
NSMutableArray *bandArray = [NSMutableArray array];
for (NSDictionary *bandDict in parsedResult) {
[bandArray addObject:[JNKBand bandWithDictionary:bandDict]];
}
if ([self.delegate respondsToSelector:@selector(bandArrayArrived:)]) {
[self.delegate bandArrayArrived:bandArray];
}
}else{
NSLog(@"Error parsing bands, calling delegate...");
if ([self.delegate respondsToSelector:@selector(bandArrayFailed)]) {
[self.delegate bandArrayFailed];
}
}
}else{
if ([self.delegate respondsToSelector:@selector(bandArrayFailed)]) {
[self.delegate bandArrayFailed];
}
}
}
The weird thing is that once the connection is finished it also eventually calls loadFileFromDisk but this works smoothley…
This is running on the main thread which is blocking everything else. You will have to do the loading in the background. Use
performSelectorInBackground:withObjectto do the loading in the background and if the delegate method is supposed to affect the UI, you should send the request back to the main thread.