我们需要在主线程,nsoperation中执行nsoperation的main()

时间:2014-09-26 17:35:28

标签: ios objective-c nsoperation nsoperationqueue

我正在iOS上开展NSOperation并完全迷失方向。我查看一些文档并注意到对于start方法,一些示例代码在主线程中执行它,一些在后台线程中执行。所以我直接根据给定的示例代码尝试一下。以下是UrlDownloadOperation.m(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];
}

日志显示哪个开始和结束以及队列中剩余的操作数。最后,总数为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

  3. 对不起,很长的帖子。我希望我能帮助你理解我的问题。先谢谢

1 个答案:

答案 0 :(得分:0)

  

为什么我们必须在主线程中执行start。我认为我们不应该因为我们正在下载数据而应该在后台线程中发生。

start方法在主线程上运行很麻烦,因此它会在主运行循环上调度自身,从而确保调用委托。但是,当以这种方式使用时,NSURLConnection的所有工作都会发生asynchronously,因此您不必担心阻塞主线程。

  

为什么以及何时我们决定这样做是当前如上所述返回YES。

isConcurrent是从NSOperation继承的方法,如果您的操作并发运行,则需要覆盖该方法。来自NSOperation参考页:

  

如果要实现并发操作,则必须覆盖此操作   方法并从您的实现返回YES。欲获得更多信息   关于并发和非并发的区别   操作,请参阅“并发与非并发操作。”