Question

I'm using NSURLConnection as listed below. I have three questions about this class. When I concatenate the url value, the debugger hits this line twice but not the line above it:

if (theConnection){

The second time I get EXC_BAD_ACCESS. Using the first url assignment (commented out) works fine.

1.) What's the difference?

- (void)applicationDidFinishLaunching:(UIApplication *)application {

//NSString *url = @"http://www.abc.com/afile.mp4";

NSString *temp = @"afile.mp4";
NSString *url = [@"http://www.abc.com/" stringByAppendingString:temp];

theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] 
                                     cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
[url release]; 

NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
    receivedData=[[NSMutableData data] retain];
}

2.) If I change the file name to afile.mp, the request goes through and [receivedData length] has a value of around 1600 when

    - (void)connectionDidFinishLoading:(NSURLConnection   *)connection

gets hit. Is there a way to accurately check if receivedData has the actual data you are requesting. The target file is about 7MB but can vary from 1.5MB to 9MB. The resource I requested wasn't there but does anything indicate that?

3.) I'm doing this in my app delegate. The only protocol there is UIApplicationDelegate. How do all of the NSURLConnection methods work if there isn't a delegate for them?

Was it helpful?

Solution

1.) What's the difference?

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    //NSString *url = @"http://www.abc.com/afile.mp4";
    NSString *temp = @"afile.mp4";
    NSString *url = [@"http://www.abc.com/" stringByAppendingString:temp];

    theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] 
                                                                             cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
    [url release]; 

The difference is that one of these lets you get away with releasing something you don't own and the other doesn't.

You didn't alloc it, copy it, or retain it, so you don't own it, so don't release it.

As an implementation detail, string literals don't implement reference-counting. String literal objects will ignore you when you try to retain or release them. That's why the version where you release a string literal doesn't crash, and the version where you create a new string and release that does. But this is an implementation detail—don't rely on it for anything. Always assume that releasing something you don't own will cause a crash.

Is there a way to accurately check if receivedData has the actual data you are requesting.

As opposed to an error document? Check the response code.

As opposed to some other data? You could use hashes, although how you determine the correct hash to expect would be up to you. However, it's probably easier to just have faith that the server won't give you the wrong file.

The resource I requested wasn't there but does anything indicate that?

Yes. Implement connection:didReceiveResponse: and check the response code.

Note that if the server is using mod_speling or something similar, it may correct your URL instead of returning an error—for example, by changing the “afile.mp” that you requested to the “afile.mp4” that actually exists.

3.) I'm doing this in my app delegate. The only protocol there is UIApplicationDelegate. How do all of the NSURLConnection methods work if there isn't a delegate for them?

You said delegate:self, so you're the connection's delegate.

On the Mac, at least, NSURLConnection categories the methods onto NSObject, so they're always available, at least in no-op form. You override these implementations, so when NSURLConnection sends your connection delegate (you) those messages, they go through to the implementations you provided.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top