2014-09-26 89 views
0

我在iOS的NSOperation上工作並且完全丟失。我查閱了一些文檔,注意到對於start方法,一些示例代碼在主線程中執行它並且一些在後臺線程中執行。所以我直接試着根據給定的示例代碼嘗試一下。下面是UrlDownloadOperation.m(的NSOperation的子類):我們是否需要在主線程中執行nsoperation的main(),nsoperation

- (BOOL)isConcurrent { 
    return YES; 
} 


-(void)main { 


} 

- (void)start 
{ 
    if (![NSThread isMainThread]) 
    { 
     [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO]; 
     return; 
    } 

    NSLog(@"opeartion for <%@> started in mainThread = %d.", _url,[NSThread isMainThread]); 

    [self willChangeValueForKey:@"isExecuting"]; 
    _isExecuting = YES; 
    [self didChangeValueForKey:@"isExecuting"]; 

    NSURLRequest * request = [NSURLRequest requestWithURL:_url]; 
    _connection = [[NSURLConnection alloc] initWithRequest:request 
                delegate:self]; 
    if (_connection == nil) 
     [self finish]; 

} 

爲了執行該操作,我做:

NSArray * urls = [NSArray arrayWithObjects:@"http://people.csail.mit.edu/gremio/logos/google.jpg",            
        @"http://www.google.com/", 
        @"http://www.apple.com/", 
        nil]; 

for (NSString * url in urls) { 
    UrlDownloaderOperation * operation = 
     [UrlDownloaderOperation urlDownloaderWithUrlString:url]; 
    [_queue addOperation:operation]; 
} 

日誌顯示我,其中一個開始和完成,有多少操作留在queue.Eventually,總爲0

2014-09-26 13:06:13.369 Concurrent[37401:303] Queue size: 1 
2014-09-26 13:06:13.370 Concurrent[37401:303] Queue size: 2 
2014-09-26 13:06:13.370 Concurrent[37401:303] Queue size: 3 
2014-09-26 13:06:13.370 Concurrent[37401:303] opeartion for <http://people.csail.mit.edu/gremio/logos/google.jpg> started in mainThread = 1. 
2014-09-26 13:06:13.370 Concurrent[37401:303] opeartion for <http://www.google.com/> started in mainThread = 1. 
2014-09-26 13:06:13.370 Concurrent[37401:303] opeartion for <http://www.apple.com/> started in mainThread = 1. 
2014-09-26 13:06:13.371 Concurrent[37401:303] operation for <http://people.csail.mit.edu/gremio/logos/google.jpg> finished. status code: 200, error: (null), data size: 283114 
2014-09-26 13:06:13.371 Concurrent[37401:303] Queue size: 2 
2014-09-26 13:06:13.372 Concurrent[37401:303] operation for <http://www.apple.com/> finished. status code: 200, error: (null), data size: 9380 
2014-09-26 13:06:13.372 Concurrent[37401:303] Queue size: 1 
2014-09-26 13:06:13.600 Concurrent[37401:303] operation for <http://www.google.com/> finished. status code: 200, error: (null), data size: 9970 
2014-09-26 13:06:13.601 Concurrent[37401:303] Queue size: 0 

如果我拿出

if (![NSThread isMainThread]) 
    { 
     [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO]; 
     return; 
    } 

所有的操作都開始了,但是我根本沒有收到任何來自他們委託的響應,現在我的隊列仍然包含3個操作。

2014-09-26 13:11:55.806 Concurrent[38365:303] Queue size: 1 
2014-09-26 13:11:55.806 Concurrent[38365:303] Queue size: 2 
2014-09-26 13:11:55.806 Concurrent[38365:3123] opeartion for <http://people.csail.mit.edu/gremio/logos/google.jpg> started 
2014-09-26 13:11:55.807 Concurrent[38365:2007] opeartion for <http://www.google.com/> started 
2014-09-26 13:11:55.807 Concurrent[38365:303] Queue size: 3 
2014-09-26 13:11:55.807 Concurrent[38365:1003] opeartion for <http://www.apple.com/> started 

我的問題是

  1. 爲什麼我們在主線程中執行start。我認爲我們不應該因爲我們正在下載數據而應該發生在後臺線程中。

  2. 爲什麼當我們決定做isCurrent返回YES像上面那樣。

對不起,很長的文章。我希望我能用你的幫助理解我的問題。先進的感謝

回答

0

爲什麼我們必須在主線程中執行啓動。我認爲我們不應該因爲我們正在下載數據而應該發生在後臺線程中。

start方法需要努力在主線程上運行,以便它在主運行循環上調度自己,以確保委託將被調用。當使用這種方式時,雖然NSURLConnection的工作都發生在asynchronously,所以你不必擔心阻塞主線程。

爲什麼當我們決定做isCurrent返回YES就像上面一樣。

isConcurrent是一種繼承自NSOperation的方法,如果您的操作併發運行,則需要覆蓋該方法。從NSOperation參考頁:

如果要實現並行操作,必須重寫此 方法,並從您的實現返回YES。有關併發和非併發 操作之間差異的更多信息,請參閱「併發與非併發操作」。「

+0

感謝您的評論,但我仍然迷失在第一個問題(啓動方法)。如果你可以給我一些參考,它也是有幫助的。 – tranvutuan 2014-09-26 20:06:53