[ios]NSOperation 不发生在后台线程

发布时间: 2017/3/20 22:30:10
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我创建了 NSOperation 子类来处理一些 zip 存档操作。无论发生什么,如果我重写 -start-main 总是会发生的这个代码块︰

if ([NSThread isMainThread]) {
    NSLog(@"I am in the main thread");
    return;
}

你知道什么吗?

我试着添加此块︰

- (void) start {  //also tried overriding main

    if ([NSThread isMainThread]) {
        NSLog(@"In main thread, trying again");
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            [self start];
        });
        return;
        //hard working code etc...
        //cpu intensive zip operations...
    }

但这会导致系统崩溃, EXC_BAD_ACCESS 违反指向 dispatch_async 线。

解决方法 1:

不管发生什么,如果我重写-开始或主要这个代码块总是事情︰

主要操作队列在主线程上运行。从文档 +[NSOperationQueue mainQueue] :

返回的队列执行操作在主线程上。主线程的运行回路控制这些操作的执行时间。

所以,在另一个线程中运行是一种什么队列添加操作,如何你不写操作的代码。如果你想你操作在不同的操作队列上运行,你需要创建您自己使用的队列

NSOperationQueue* aQueue = [[NSOperationQueue alloc] init];

在并发编程指南添加到操作队列的操作中,可以找到一个例子。

但这会导致系统崩溃,指着 dispatch_async 线 EXC_BAD_ACCESS 违反。

这听起来像 -[NSOperation start] 可能并不是可重入。您的代码有效地在两个不同的线程上执行相同的方法。事实上,看看文档 -start ,很明显你的代码不起作用︰

如果你想要手动执行您的操作,您可以显式调用此方法。然而,它是一个程序员错误调用此方法,这就是已经在操作队列操作对象上的或排队操作后调用此方法。一旦你将操作对象添加到队列,队列假定为它的所有责任。[加着重号。-迦勒]

换句话说,不要那样做。

官方微信
官方QQ群
31647020