到目前为止,这是我遇到的最奇怪的问题。
我在UINavigationController上有一个UINavigationController,我想使用NSInvocationOperation在viewDidAppear上调用一个方法,这样当视图变得可见时,它就可以在后台线程上运行。
问题是,如果我在操作(在本例中是testMethod方法)完成运行之前弹出视图控制器,那么应用程序就会崩溃。
如果我在操作完成后弹出视图控制器,一切都很好。
当应用程序崩溃时,它以"EXC-BAD-ACCESS“停止在超级dealloc,并给出以下错误。
bool _WebTryThreadLock(bool),xxxxxxxxx:尝试从主线程或web线程以外的线程获取web锁。这可能是从辅助线程调用UIKit的结果。现在崩溃..。
这是我的代码(超级简化)..
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSInvocationOperation *theOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(testMethod) object:nil];
[operationQueue addOperation:theOperation];
[theOperation release];
}
- (void)testMethod
{
NSLog(@"do some stuff that takes a few seconds to complete");
}
- (void)dealloc
{
[_tableView release];
[super dealloc];
}testMethod有一些需要几秒钟才能完成的代码。我只有几条线索,我真的不知道如何从哪里开始调试。
我的UITableViewDelegate和UITableViewDataSource中有一些非常复杂的代码,我真的不知道从哪里开始调试它。我真的希望我不必一行行,也不要因为这个而重写整件事。
关于我该去哪找有什么建议?
发布于 2011-09-07 13:39:55
问题可能是您的视图控制器的最后一个引用是保存它的操作队列,这意味着当操作清除时,您在后台线程中调用(或让系统调用)一些UIKit方法(一个大的no)。
为了防止这种情况发生,您需要在操作结束时向主线程上的控制器发送一条保持活动的消息,方法是在testMethod的最后一行中添加类似的内容。
[self performSelectorOnMainThread:@selector(description) withObject:nil waitUntilDone:NO];在操作队列释放视图控制器之前,仍然有可能对此消息进行处理,但这种可能性非常小。如果它还在发生,你可以这样做:
[self performSelectorOnMainThread:@selector(keepAlive:)
withObject:[NSNumber numberWithBool:YES]
waitUntilDone:NO];
- (void)keepAlive:(NSNumber *)fromBackground
{
if (fromBackground)
[self performSelector:@selector(keepAlive:) withObject:nil afterDelay:1];
}通过向主线程上的视图控制器发送消息,它将使对象保持活动状态(NSObject将保留视图控制器直到主线程处理该消息)。如果在延迟后执行选择器,它还将使视图控制器保持活动状态。
发布于 2011-09-07 13:56:41
您正在崩溃,因为控制器仍然试图使用您的tableView引用,并且由于您已弹出了viewController,所有东西都会在dealloc中消失,而tableView仍然在填充自己。您可以尝试在dealloc方法中询问您的操作是否仍在运行,因此您可以取消它,并且一切都应该很好。
一旦将操作添加到队列中,操作就无法控制。队列接管并处理该任务的调度。但是,如果您稍后决定不想执行操作--因为用户按了进度面板中的cancel按钮或退出应用程序--您可以取消操作,以防止它不必要地占用CPU时间。为此,您可以调用操作对象本身的cancel方法,或者调用NSOperationQueue类的NSOperationQueue方法。
取消操作并不会立即迫使它停止正在执行的操作。虽然所有操作都需要尊重isCancelled返回的值,但您的代码必须显式检查此方法返回的值,并根据需要中止。NSOperation的默认实现确实包括检查是否取消。例如,如果在调用开始方法之前取消操作,则开始方法退出而不启动任务。。
https://stackoverflow.com/questions/7334647
复制相似问题