我正在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
我的问题是
为什么我们必须在主线程中执行start
。我认为我们不应该因为我们正在下载数据而应该在后台线程中发生。
为什么以及何时我们决定isCurrent
如上所述返回YES
。
对不起,很长的帖子。我希望我能帮助你理解我的问题。先谢谢
答案 0 :(得分:0)
为什么我们必须在主线程中执行start。我认为我们不应该因为我们正在下载数据而应该在后台线程中发生。
start
方法在主线程上运行很麻烦,因此它会在主运行循环上调度自身,从而确保调用委托。但是,当以这种方式使用时,NSURLConnection
的所有工作都会发生asynchronously,因此您不必担心阻塞主线程。
为什么以及何时我们决定这样做是当前如上所述返回YES。
isConcurrent
是从NSOperation
继承的方法,如果您的操作并发运行,则需要覆盖该方法。来自NSOperation
参考页:
如果要实现并发操作,则必须覆盖此操作 方法并从您的实现返回YES。欲获得更多信息 关于并发和非并发的区别 操作,请参阅“并发与非并发操作。”