我创建了一个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
行。
答案 0 :(得分:7)
无论如何,如果我覆盖-start或-main这段代码总是会发生:
主操作队列在主线程上运行。来自+[NSOperationQueue mainQueue]
的文档:
返回的队列在主线程上执行操作。主要的 thread的运行循环控制这些操作的执行时间。
因此,在另一个线程中运行是您添加操作的队列的问题,而不是您编写操作代码的方式。如果您希望操作在不同的操作队列上运行,则需要使用
创建自己的队列NSOperationQueue* aQueue = [[NSOperationQueue alloc] init];
您可以在“并发编程指南”中找到Adding Operations to an Operation Queue中的示例。
但这会导致崩溃,指向dispatch_async行的EXC_BAD_ACCESS违规。
听起来-[NSOperation start]
可能不是可重入的。您的代码在两个不同的线程上有效地执行相同的方法。事实上,看看the docs for -start
,显然你的代码不起作用:
如果你想执行你的方法,你可以明确地调用这个方法 手动操作。但是,调用它是一个程序员错误 已经在操作队列中的操作对象的方法 或者在调用此方法后对操作进行排队。一旦你添加了 操作对象到队列,队列承担所有责任 它。 [重点补充。 -Caleb]
换句话说,不要这样做。