0

我正在编写一个 iPad 应用程序,它根据从服务器抓取的一些 JSON 数据填充 UI。因此,我正在使用 NSURLConnection 进行初始连接:

// Create the request.
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://foo.com/login"]];
[request setHTTPMethod:@"POST"];

NSString* credentials = @"username=testFoo&password=passFoo";

self.fFooConnectionData = [credentials dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:self.fFooConnectionData];

self.fFooDataConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[self.fFooDataConnection start];

现在,我的问题是我可以在“connectionDidX”委托函数中捕获响应,但是对于后续步骤,我应该如何进行?如果是同步连接,事情就简单了,我就等返回值,但是如果是异步连接,后续的请求怎么处理呢?如何区分一个事件(如登录)和另一个事件(如请求 UI 的特定数据)?

4

1 回答 1

0

每个异步方法、函数或异步操作都有一种方法来“通知”客户端它已经完成。

NSURLConnection使用委托方法向委托发送“事件”信号。委托方法connectionDidFinishLoading:分别connection:didFailWithError:表示数据最终被下载,分别表示发生了错误。

“调用站点”(在 的情况下是委托实例)现在应该委托方法中NSURLConnection定义下一步要做什么。

您只需要确保下一个操作的“执行上下文”是适当的:例如,在某个设置中NSURConnection,可以在私有辅助线程上调用委托方法。假设客户想要使用下载的数据并将其显示在表格视图中。UIKit 方法只能在主线程上调用。因此,需要通过例如将操作分派到适当的队列(主队列)来确保这一点。

异步处理更复杂NSURLConnection的任务,信号异步事件的委托方法很快变得笨拙。更好的方法是对网络任务使用异步操作。您可以将您的NSURLConnection任务“包装”到NSOperation用于该专用目的的子类中。你得到的是一个可能复杂的类,它在内部处理所有复杂性并提供了一个易于使用的 API。客户端需要指定一个“完成处理程序”(一个块)而不是处理委托方法。这极大地减少了对象之间的依赖关系并极大地简化了您的编码任务。

然后,它与上面已经说过的基本相同:

“调用站点”(即NSOperation网络子类的客户端)现在应该在完成处理程序中定义下一步要做什么

好吧,即使是NSOperation子类也可能变得笨拙,特别是如果您必须为请求设置许多参数并进行所有令人讨厌和复杂的错误处理。您偶尔可能想要的是一种更简单的调用方式。所以,你可以定义一个非常特殊的“方法”说,

-(void) fetchMessagesWithUser:(User*)user completion:(completion_t)completionHandler;

在内部,您基于您的子类实现该方法,该子类NSOperation本身是在NSURLConnection. 您将所有讨厌的样板文件都放入其中,包括广泛的错误检查。

然后,您的代码变得更加“干净”:

- (void) fetchUserMessages 
{
   [self fetchMessagesWithUser:self.currentUser completion:^(id result){
        // result is an NSData containing JSON (array of messages for a user) or an NSError
        if (![result isKindOfClass:[NSError class]]) {
             NSArray* messages = ...  // invoke JSON parser
             dispatch_async(dispatch_get_main_queue(), ^{
                 [self updateViewWithMessages:messages];
             });
        }
        else {
            [self handleError:result];
        }
   }];
}
于 2013-08-14T10:35:08.107 回答