Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using custom subclass of NSURLConnection, how does it "find" the additional data in the class later?

This blog offers a nice solution for handling multiple NSURLConnections: make a custom "CustomURLConnection" class that has an additional tag property.

http://blog.emmerinc.be/index.php/2009/03/02/custom-nsurlconnection-class-with-tag/

http://blog.emmerinc.be/index.php/2009/03/15/multiple-async-nsurlconnections-example/

Basically, he has simply added a tag property to the exsisting NSURLConnection:

CustomURLConnection.m

- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately tag:(NSString*)tag {
   self = [super initWithRequest:request delegate:delegate startImmediately:startImmediately];

   if (self) {
      self.tag = tag;
   }
   return self;
}

then, later in the normal NSURLConnection loading methods, you can do:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

   //Log the connection’s tag
   CustomURLConnection *ttttag = (CustomURLConnection *)connection; // **HERE**
   NSLog(@”%@”, ttttag.tag);


   NSMutableData *dataForConnection = [self dataForConnection:(CustomURLConnection*)connection];
   [connection release];
}

So, that's where I'm having trouble. The way I see it, this is how things go:

  • I create a "connection+tag"
  • The first code snippet I posted above creates a regular "connection" (no tag), which will eventually call the the normal NSURLConnection methods like connectionDidFinishLoading. What happens to the tag at this point?
  • In the connectionDidFinishLoading method I'm able to cast the connection back into a "connection+tag", then find that missing tag information that had been discarded. How?

Maybe I'm just confusing myself, but it seems as if the tag was discarded when it starts down the normal NSURLConnection path. But then by casting it as the subclass, I'm again able to recover the tag property. Where did it live/go in the mean time?

Could someone with a better understanding of inheritance explain this to me?

like image 251
ck_ Avatar asked Nov 30 '11 18:11

ck_


2 Answers

With this code:

[[CustomURLConnection alloc] initWithRequest:... delegate:... startImmediately:... startImmediately tag:...];

you create an instance of CustomURLConnection. Now here is where your understanding is wrong: this CustomURLConnection object can freely call all methods of its superclasses but it will always remain a CustomURLConnection. The tag is always there.

The methods that are defined in the superclass such as initWithRequest:delegate:startImmediately: don't know about the tag but they don't have to, either. When the delegate method gets called:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

the connection argument is the very same CustomURLConnection that you created yourself above. The type in the method signature is different but that doesn't matter; because you know that this connection is of the CustomURLConnection type, you can just cast the connection object to the correct type and access the new property. But even if you wouldn't do that, the tag would still be there all the time.

like image 156
Ole Begemann Avatar answered Nov 15 '22 09:11

Ole Begemann


I'm not sure what you mean by:

The first code snippet I posted above creates a regular "connection" (no tag).

What you've done here is create a subclass of NSURLConnection. Anywhere you can use the latter, you can use the former. NSURLConnection* means "a pointer to an NSURLConnection* or a subclass of it." So the original object you created was a CustomURLConnection and it included an extra ivar. That ivar doesn't disappear just because intermediary users refer to it by its superclass.

like image 31
Rob Napier Avatar answered Nov 15 '22 07:11

Rob Napier