当操作添加到NSOperationQueue时,NSURLConnection在NSBlockOperation中不起作用

时间:2014-04-11 13:07:31

标签: ios nsurlconnection nsoperationqueue

我在NSBlockOperation中使用NSURLConnection,我将此操作添加到NSOperationQueue.But它无法正常工作。当我调用NSBlockOperation的start方法然后它工作但是当我将NSBlockOperation添加到NSOperationQueue时它无法工作。

请有人帮助我吗???

NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
[operationQueue setMaxConcurrentOperationCount:1];

NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
    NSURL *url = [NSURL URLWithString:@"http://api.kivaws.org/v1/loans/search.json?status=fundraising"];
    NSURLRequest *req = [NSURLRequest requestWithURL:url];

    NSURLConnection  *connection1 = [[NSURLConnection alloc] initWithRequest:req delegate:self];
    [connection1 start];
}];

NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
    NSURL *url = [NSURL URLWithString:@"http://urls.api.twitter.com/1/urls/count.json"];
    NSURLRequest *req = [NSURLRequest requestWithURL:url];


    NSURLConnection  *connection2 = [[NSURLConnection alloc] initWithRequest:req delegate:self];
    [connection2 start];
}];

[operation2 addDependency:operation1];

[operationQueue addOperation:operation1];
[operationQueue addOperation:operation2];

我还将NSURLConnectionDataDelegate实现为:

  • (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
  • (void)connection:(NSURLConnection *)conn didReceiveResponse:(NSURLResponse *)response

请帮忙 感谢

2 个答案:

答案 0 :(得分:0)

尝试做:

NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
    NSURL *url = [NSURL URLWithString:@"http://api.kivaws.org/v1/loans/search.json?status=fundraising"];
    NSURLRequest *req = [NSURLRequest requestWithURL:url];

    NSURLConnection  *connection1 = [[NSURLConnection alloc] initWithRequest:req delegate:self];
    [connection1 scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
    [connection1 start];
}];

原因是NSURLConnection尝试在它已经启动的线程的运行循环上提供它的委托更新,在你的情况下它是另一个线程,支持在NSOperationQueue的队列中,该线程可能在您的网络呼叫返回时被回收,并且没有运行循环来处理源,因此您不会让您的代表被击中。使用这种方法,您将在主运行循环上获得这些事件,这肯定是活着的。

使用NSURLConnection的方式是异步,而不是sendSynchronousRequest:returningResponse:error:使用它的方式,这是同步的。因此,在另一个线程中启动它没有意义。

但如果您只是尝试进行异步网络通信,则可以使用sendAsynchronousRequest:queue:completionHandler:方法真正简化代码。这样你就不需要实现任何代表了。您可能遇到的唯一问题是,如果有某种身份验证,那么您需要采用您所采用的方法。

答案 1 :(得分:0)

我发现您的代码至少存在两个问题:

  1. 您必须在- (void)start之后致电- (id)initWithRequest:(NSURLRequest *)request delegate:(id < NSURLConnectionDelegate >)delegate。它始于它自己。
  2. - (id)initWithRequest:(NSURLRequest *)request delegate:(id < NSURLConnectionDelegate >)delegate是异步的,所以你必须保持你的操作一直处于活动状态,同时它的运行状态以及你的operationQueue不应该是&#34;堆栈&#34;变量
  3. 如何轻松解决问题:

    1. 在blockOperations中使用+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error。它在执行加载时阻止当前线程。
    2. 示例:

      NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
          NSURL *url = [NSURL URLWithString:@"http://urls.api.twitter.com/1/urls/count.json"];
          NSURLRequest *req = [NSURLRequest requestWithURL:url];
      
          NSURLResponse *response = nil;
          NSError *error = nil;
          NSData *data = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
      }];
      

      还有很多其他方法,但第一种方法应该能很好地运作。