NSOperationQueue避免将视图控制器推入导航控制器堆栈?

时间:2011-05-23 05:15:57

标签: iphone uinavigationcontroller nsoperation

我有一个视图控制器,它是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];
}

Parser工作得很好但是在我的自定义委托方法中,我已经调用推送控制器堆栈顶部的视图控制器,视图控制器正确初始化但新的视图控制器没有被推入屏幕。

我已经编辑了使用主线程和后台线程的问题,而后台线程正常工作以解析主线程只是初始化并且不推送视图控制器。 有什么问题?

1 个答案:

答案 0 :(得分:2)

您需要在主线程上推送视图控制器。使用performSelectorOnMainThread:withObject:waitUntilDone:在主线程上调用方法。

如果您有可能推送多个视图控制器,如果将视图控制器推入堆栈而另一个视频控制器被动画化,则应用程序将崩溃。在这种情况下,您应指定animated:NO,或者在NSArray中收集视图控制器并使用setViewControllers:animated:将它们添加到堆栈中。


回答您的更新问题:您不需要通过parseOperation:致电performSelectorInBackground:withObject:,因为NSOperationQueue会执行它在单独的线程中创建的NSOperation。我建议在您的NSOperation子类中添加delegate属性并遵循以下模式:

MyViewController.m

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyParseOperation *parseOp = ...
    parseOp.delegate = self;
    [myOperationQueue addOperation:parseOp];
}

// Called by MyParseOperation
- (void)operationCompletedWithXML:(XML *)parsedXML
{
    // Use parsedXML to create and configure a view controller
    MyCustomViewController *vc = ...

    // Animation is OK since only one view controller will be created
    [self.navigationController pushViewController:vc animated:YES];
}

MyParseOperation.m

// Call this method once the XML has been parsed
- (void)finishUp
{
    // Invoke delegate method on the main thread
    [self.delegate performSelectorOnMainThread:@selector(operationCompletedWithXML:) withObject:self.parsedXML waitUntilDone:YES];

    // Perform additional cleanup as necessary
}