开发者

Making non-self delegate in obj-c

In order to use asynchronous http requests in objective c, you need to set a delegate to NSURLConnection. The problem is that I need to make multiple http requests, so开发者_如何学运维 having the same delegate (self) wont work.

What is the best way to go about this? Should I make a new delegate class for each http request? Are these delegates just NSObjects?


You have a few options. The two most most common are:

  • Make a new class for each connection (yes, a subclass of NSObject) and set them as delegates -- have them carry out whatever logic you need when the data is loaded

  • Set one class as the delegate and store references to all of your NSURLConnections. That way, when your delegate gets - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data called, you can test which NSURLConnection is being used (eg if ([connection == myConnection]) -- or whichever delegate method you're implementing)


What I do is make a class that will handle downloading a file, and notify me when it is done through a selector. I pass it a delegate, a selector and the Info it needs to perform the download.

- (void) downloadFileFrom:(NSString*) httpLocation respondAt:(SEL)selector on:(id)target withParam:(id)param
{
    self.finishSelector = selector;
    self.delegate = target;
    self.responseParams = param;
}

the Class is its own NSURLConnection delegate. Therefore the instance is separated from the others that I may instantiate, And it handles creating its own result for me to work with. I hold onto the param object. which could be anything.

At the end of the download it does a performSelector: on the delegate. passing itself to the delegate.

if ([self.target respondsToSelector:self.selector])
{
    [self.target performSelector:self.selector withObject:self.param];
}

then you can create an instance of the downloader and call your method... telling it where to reply to you.

MyDownloader downloader = [[MyDownloader alloc] init];
[downloader downloadFileFrom:@"http://www.mydomain.com/myimage" respondAt:@selector(myFileIsComplete:) on:self withParam: downloader];
[downloader autorelease];

another option is to create a @protocol for your class to respond at, and have you delegate conform to the responder.


That should work, but there is another option to consider. You could make a generic class that creates and calls the NSURLConnection provided they are common enough. Then keep an NSArray or NSDictionary of the classes. One for each connection.

Example: I have an app that needs to download several photos simultaneously. Therefore, I have a GetFlickrPhoto class. It has a custom init method that receives the URL and any other necessary info. Each individual class creates the NSURLConnection and can safely set the delegate to self

This helps keep things contained and very manageable/reusable.

To take it a step further:

The app I mentioned before, also needed to download JSON feeds. So I made a GenericDownload class that took in URL and asynchronously downloaded the NSData and then returned the NSData to the calling delegate via defined success/failure protocols. It didn't care what the NSData contained.

I remodeled GetFlickrPhoto to call GenericDownload and use the returned NSData for a photo. I then made a GetJSON class that also called GenericDownload and parsed the returned NSData into a JSON feed.

Takes a bit more time but in the end you will be glad for maintenance and future projects.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜