2014-04-11 79 views
0

我在NSBlockOperation中使用NSURLConnection,我將此操作添加到NSOperationQueue.But它不工作。當我調用NSBlockOperation的啓動方法,然後它工作,但它不當我將NSBlockOperation添加到NSOperationQueue時工作。NSURLConnection不工作在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爲:

  • (無效)連接:(NSURLConnection的*)連接didReceiveData:(NSData的*)數據
  • (無效)連接:(NSURLConnection的*)美國康涅狄格州didReceiveResponse:(NSURLResponse *)響應

請幫 感謝

+0

*爲什麼*你在使用NSOperationQueue並在NSOperationQueue上執行的塊中啓動(僅re * only * start *)NSURLConnection?你可以看看這裏:https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html#//apple_ref/doc/uid/20001697-SW12 **調度委託方法調用** – CouchDeveloper

回答

0

我看到至少有兩個問題與您的代碼:

  1. - (id)initWithRequest:(NSURLRequest *)request delegate:(id <NSURLConnectionDelegate>)delegate後,您不能調用- (void)start。它自己開始。
  2. - (id)initWithRequest:(NSURLRequest *)request delegate:(id <NSURLConnectionDelegate>)delegate是異步的,所以你必須保持你的操作一直活着,而它的工作方式和你的operationQueue不應該是一個「堆棧」變量。

如何來解決它:

  1. 使用+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error您blockOperations內。它在執行加載時阻塞當前線程。

例子:

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]; 
}]; 

還有很多其他的方法,但第一個應該很好地工作。

+0

感謝它正在工作。 但在我的代碼中有什麼問題?爲什麼NSURLConnectionDelegates沒有擊中?是因爲runloop?我也試過 [connection1 scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; [connection1 start]; 但仍然代表沒有打。 –

+0

你的代碼的主要問題是,當NSURLConnection開始工作,並打算使用NSURLConnectionDelegates調用線程完成並釋放其所有資源,包括您的NSURLConnection。因此,要從該線程中的NSURLConnection實例接收調用,必須在加載數據時添加手動線程阻塞,並在完成後解除阻止。解決我提到的問題也很好。 – SVGreg

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:簡化你的代碼。這樣你就不需要實現任何代表。您可能遇到的唯一問題是,如果有某種身份驗證,那麼您將需要使用該方法。

+0

我明白你已經解釋,但[連接1 scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; 不起作用。把這一行放在代表沒有打。 –

相關問題