NSOperationQueue 避免将视图控制器推入导航控制器堆栈?
我有一个视图控制器,它是 UIViewController 的子类,其中包含表视图,并且表视图中的每一行都链接到不同的 xml url。 我创建了一个解析器类,它是 NSOperation 的子类,并实现了在选择每一行时解析 XML 文件的方法,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self performSelectorOnMainThread:@selector(pushView) withObject:nil waitUntilDone:NO];
[self performSelectorInBackground:@selector(parseOperation:) withObject:indexPath];
}
- (void)pushView {
detailView = [[viewDetailsController alloc] initWithNibName:@"viewDetailsController" bundle:nil];
[self.navigationController pushViewController:detailView animated:YES];
}
- (void)parseOperation:(NSIndexPath *)indexPath {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
self.queue = [[NSOperationQueue alloc] init];
parserClass *parser = [[parserClass alloc] initWithParseUrl:[[self.arrayOfUrls objectAtIndex:indexPath.row]delegate:self];
[queue addOperation:parser];
[parser release];
[pool release];
}
解析器工作得很好,但在其自定义委托方法中,我调用了将视图控制器推送到导航控制器堆栈的顶部,视图控制器正确初始化,但新的视图控制器未推送到屏幕中。
我编辑了使用主线程和后台线程的问题,而后台线程可以正确解析主线程,只是初始化并且不会推送视图控制器。 问题是什么 ?
I have a view controller that is sub class of UIViewController which has table view into it and each rows in table view is linked to distinct xml url.
I made a parser class that is sub class of NSOperation and implemented methods to parse the XML file on selection of each row as,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self performSelectorOnMainThread:@selector(pushView) withObject:nil waitUntilDone:NO];
[self performSelectorInBackground:@selector(parseOperation:) withObject:indexPath];
}
- (void)pushView {
detailView = [[viewDetailsController alloc] initWithNibName:@"viewDetailsController" bundle:nil];
[self.navigationController pushViewController:detailView animated:YES];
}
- (void)parseOperation:(NSIndexPath *)indexPath {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
self.queue = [[NSOperationQueue alloc] init];
parserClass *parser = [[parserClass alloc] initWithParseUrl:[[self.arrayOfUrls objectAtIndex:indexPath.row]delegate:self];
[queue addOperation:parser];
[parser release];
[pool release];
}
Parser works great but in its custom delegate method I have called to push view controller on the top of the navigation controller stack, the view controller initializes correctly but the new view controller is not pushed into the screen.
I have edited the question for using the main thread and background thread while the background thread works correctly for parsing the main thread just initializes and does not push view controller.
What is the problem ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要将视图控制器推送到主线程上。使用
performSelectorOnMainThread:withObject:waitUntilDone:
在主线程上调用方法。如果您有可能推送多个视图控制器,则当一个视图控制器被推送到堆栈上而另一个视图控制器正在进行动画处理时,您的应用程序将会崩溃。在这种情况下,您应该指定
animated:NO
,或者收集 NSArray 中的视图控制器并使用setViewControllers:animated:
将它们添加到堆栈中。回应您更新的问题:您不需要通过
performSelectorInBackground:withObject:
调用parseOperation:
因为 NSOperationQueue 无论如何都会执行它在单独线程中创建的 NSOperation 。我建议向您的 NSOperation 子类添加一个delegate
属性,并遵循以下模式:MyViewController.m
:MyParseOperation.m
:You need to push the view controller(s) on the main thread. Use
performSelectorOnMainThread:withObject:waitUntilDone:
to invoke a method on the main thread.If there is a possibility that you will push multiple view controllers, your app will crash if a view controller is pushed onto the stack while another is being animated in. In this case, you should either specify
animated:NO
, or collect the view controllers in an NSArray and usesetViewControllers:animated:
to add them to the stack.In response to your updated question: You shouldn't need to call
parseOperation:
viaperformSelectorInBackground:withObject:
since the NSOperationQueue will execute the NSOperation that it creates in a separate thread anyway. I suggest adding adelegate
property to your NSOperation subclass and following this pattern:MyViewController.m
:MyParseOperation.m
: