check which request is which from NSURLConnection

2019-09-05 17:01发布

What is the best way to check which request is which inside the delegate method:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{

}

Right now I have a NSURLConnection that I set to the NSURLConnection before making a request and inside didReceiveResponse I do:

if (self.tempConnection == connection)

however there is a possiblity this won't work for race conditions. Is there a better way to do this?

3条回答
干净又极端
2楼-- · 2019-09-05 17:34

I've looked at a bunch of different ways to do this, and I've found that by far the cleanest and easiest in order to manage is to use a block pattern. That way you are guaranteed to be responding to the right request upon completion, avoid race conditions, and you don't have any issues with variables or objects going out of scope during the asynchronous call. It's also a lot easier to read/maintain your code.

Both ASIHTTPRequest and AFNetworking APIs provide a block pattern (however ASI is no longer supported so best to go with AFNetworking for new stuff). If you don't want to use one of these libraries, but want to do it yourself, you can download the source for AFNetworking and review their implementation. However, that seems like a lot of extra work for little value.

查看更多
3楼-- · 2019-09-05 17:35

There is a better way in OS5. Forget about all those bothersome delegate messages. Let the connection build the data for you, and put your finished code right in line with your start code:

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.site.com"]];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
    NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
    NSLog(@"got response %d, data = %@, error = %@", [httpResponse statusCode], data, error);
}];
查看更多
Evening l夕情丶
4楼-- · 2019-09-05 17:41

Consider creating a separate class to serve as the delegate. Then, for each NSURLConnection spawned, instantiate a new instance of the delegate class to for that NSURLConnection

Here's some brief code to illustrate this:

@interface ConnectionDelegate : NSObject <NSURLConnectionDelegate>

...then implement the methods in the .m file

Now, I'm guessing you probably have the code you posted in a UIViewController subclass (or some other class serving different purposes)?

Wherever you are kicking off the requests, use this code:

ConnectionDelegate *newDelegate = [[ConnectionDelegate alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"<url here">]];
[NSURLConnection connectionWithRequest:request delegate:newDelegate];

//then you can repeat this for every new request you need to make
//and a different delegate will handle this
newDelegate = [[ConnectionDelegate alloc] init];
request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"<url here">]];
[NSURLConnection connectionWithRequest:request delegate:newDelegate];

// ...continue as many times as you'd like
newDelegate = [[ConnectionDelegate alloc] init];
request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"<url here">]];
[NSURLConnection connectionWithRequest:request delegate:newDelegate];

You might consider storing all the delegate objects in a NSDictionary or some other data structure to keep track of them. I'd consider using an NSNotification in connectionDidFinishLoading to post a notification that the connection is done, and to serve whatever object created from the response. Lemme know if you want code to help you visualize that. Hope this helps!

查看更多
登录 后发表回答