Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'for' loop crashes when downloading from NSMutableArray

I have 4 elements in my NSMutableArray. I have this neat code for downloading files and displaying the file's data in UITextView for testing purposes. Without the for loop, everything is fine. The code that gives me the problem is in this function:

- (void)complexDownload {
    int i;
    for (i=0; i < downloadArray.count; i++) {
        if (isBusy == NO) {
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
            downloadURL = [downloadArray objectAtIndex:i];
            NSLog(@"URL is %@", downloadURL);
            NSLog(@"Downloading object at index %i", i);
            NSURL *url = downloadURL;
            NSURLRequest *theRequest=[NSURLRequest requestWithURL:url
                                                      cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                  timeoutInterval:60.0];

            NSURLConnection *theConnection = [NSURLConnection connectionWithRequest:theRequest delegate:self];

                if (theConnection) {
                    self.downloadData = [NSMutableData data];
                    isBusy = YES;
                    NSLog(@"Busy value in download cycle equals %i, downloading", isBusy);
                } else {
                    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
                    NSLog(@"Connection failed");
                    isBusy = NO;
                }
        }
    }
}

I first thought that the problem might be in the isBusy BOOL, but even without the if condition the app crashes. The compiler gives me no error but this one: Here's the link for the big screenshot.

The rest of the functions are as follows:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [downloadData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSString *dataString = [[NSString alloc] initWithData:downloadData encoding:NSASCIIStringEncoding];
    self.dataTextView.text = dataString;
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    NSLog(@"Download finished!");
    isBusy = NO;
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"%@", error);
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}

All the NSLogged values are more than fine, the Array has got links and all the links are correct.

like image 281
Sergey Grischyov Avatar asked Dec 19 '12 14:12

Sergey Grischyov


3 Answers

My guess is that at some point either downloadArray[i] is corrupt at some point, or it's not an NSUrl. The code crashes in CFURLCopyAbsoluteURL() called from [NSURLRequest requestWithURL...].

like image 96
Krzysiek Avatar answered Dec 02 '22 19:12

Krzysiek


You take the async api initWithRequest:delegate: and try to make it synchronous by using isBusy flag. This approach is very wrong to begin with, the NSURLConnection class is smart enough, do don't need to use arbitrary flags if you use it properly. You should seriously reconsider using NSOperations or GCD. If you're planning to do more complicated connectivity programming maybe you should consider using a third party framework like RestKit.

like image 33
lawicko Avatar answered Dec 02 '22 20:12

lawicko


I think it's a problem with url-object in [NSURLRequest requestWithURL:url It is not necessary to copy the URL in an extra object. Try this:

NSLog(@"URL is %@", [downloadArray objectAtIndex:i]);
NSLog(@"Downloading object at index %i", i);
NSURL *url = [downloadArray objectAtIndex:i];

(or add self. before downloadURL)

If your downloadArray contains NSStrings:

NSURL *url = [NSURL URLWithString:[downloadArray objectAtIndex:i]];

I would recommend using external framework like [ASIHTTPRequest](http://allseeing-i.com/ASIHTTPRequest/

like image 21
flexo Avatar answered Dec 02 '22 20:12

flexo