Iphone UITableView重新加载数据,导致所有动画停止工作

Iphone UITableView重新加载数据,导致所有动画停止工作,iphone,cocoa-touch,uikit,Iphone,Cocoa Touch,Uikit,好吧,这是一个非常奇怪的问题,所以我将布局正在发生的事情,然后给出一些代码。在我的例子中,我将使用静态的视图数量,2 基础知识 我有一个UIPageControl,添加了X多个子视图。在每个子视图上,viewDidLoad是一个NSXMLParse,用于获取XML提要。一旦获得提要,就会对其进行解析,并使用解析后的数组重新加载表。每个视图上都有一个设置按钮。按下设置按钮时,运行UIModalTransitionStyleCoverVertical:Animated:YES,UINavigatio

好吧,这是一个非常奇怪的问题,所以我将布局正在发生的事情,然后给出一些代码。在我的例子中,我将使用静态的视图数量,2

基础知识
我有一个UIPageControl,添加了X多个子视图。在每个子视图上,viewDidLoad是一个NSXMLParse,用于获取XML提要。一旦获得提要,就会对其进行解析,并使用解析后的数组重新加载表。每个视图上都有一个设置按钮。按下设置按钮时,运行UIModalTransitionStyleCoverVertical:Animated:YES,UINavigationController以完整动画向上滑动到视图中。“解除”还会显示动画滑回上一个视图。如果处于“设置”中,则可以将视图推至两个深度(动画中的幻灯片)

问题
当你点击“设置”按钮时,应用程序生成并运行(未恢复)的随机时间量,动画不会出现。除了移除所有核心动画外,所有功能都正常。DismissModal只需切换回上一屏幕。NavigationController中的PushView不再具有任何动画,只会显示下一个视图

如果您退出应用程序(Kill进程)并重新启动它,它可能会在一段时间内正常工作,但在某些时候,当您点击“设置”按钮时,它将丢失所有动画

- (void)parserDidEndDocument:(NSXMLParser *)parser
{   
    NSMutableArray *tableData = ARRAY_GENERATED_HERE;
    [self.tableView reloadData];
}
详细信息
我从Apple PageControl应用程序开始做基础工作。它根据用户设置创建动态的视图量

- (void)awakeFromNib
{   
    kNumberOfPages = 2;

    // view controllers are created lazily
    // in the meantime, load the array with placeholders which will be replaced on demand
    NSMutableArray *controllers = [[NSMutableArray alloc] init];
    for (int i = 0; i < kNumberOfPages; i++)
    {
        [controllers addObject:[NSNull null]];
    }

    self.viewControllers = controllers;

    // a page is the width of the scroll view
    scrollView.pagingEnabled = YES;
    scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * kNumberOfPages, scrollView.frame.size.height);
    scrollView.showsHorizontalScrollIndicator = NO;
    scrollView.showsVerticalScrollIndicator = NO;
    scrollView.scrollsToTop = NO;
    scrollView.delegate = self;

    pageControl.numberOfPages = kNumberOfPages;
    pageControl.currentPage = 0;

    // pages are created on demand
    // load the visible page
    // load the page on either side to avoid flashes when the user starts scrolling
    [self loadScrollViewWithPage:0];
    [self loadScrollViewWithPage:1];
}


- (void)loadScrollViewWithPage:(int)page
{
    if (page < 0)
        return;
    if (page >= kNumberOfPages)
        return;

    // replace the placeholder if necessary
    SecondViewController *controller = [viewControllers objectAtIndex:page];
    if ((NSNull *)controller == [NSNull null])
    {
        controller = [[SecondViewController alloc] initWithPageNumber:page];
        [viewControllers replaceObjectAtIndex:page withObject:controller];
        [controller release];
    }

    // add the controller's view to the scroll view
    if (controller.view.superview == nil)
    {
        CGRect frame = scrollView.frame;
        frame.origin.x = frame.size.width * page;
        frame.origin.y = 0;
        controller.view.frame = frame;
        [scrollView addSubview:controller.view];
    }

}
此时,SettingsViewController将显示在视图中。但是,有时它会以适当的动画向上滑动。其他时候,它会简单地出现,所有进一步的核心动画都会被破坏,直到进程重新启动

我检查了所有NSXMLParse,并将问题缩小到一行。在我的每个子视图上都有一个tableView,在XML解析完成后,我用结果创建了一个数组并运行
[self.tableView reloadData]
。如果我注释掉那一行,表显然只加载空白,但它没有任何动画问题

- (void)parserDidEndDocument:(NSXMLParser *)parser
{   
    NSMutableArray *tableData = ARRAY_GENERATED_HERE;
    [self.tableView reloadData];
}
我的测试
我会从测试中注意到,如果kNumberOfPages设置为1而不是2,一切都很好。仅生成一个视图,不会出现动画故障。在中添加第二个视图,通常在打开设置内五次,它会出现故障

仍然没有找到解决方案,但这与
[tableView reloadData]
有关。任何洞察都会很好

丹尼尔指出了一些有意义的事情

在viewDidLoad中获取我的XML时使用:

[NSThread detachNewThreadSelector:@selector(parseXMLFileAtURL:) toTarget:self withObject:path];

- (void)parseXMLFileAtURL:(NSString *)URL
{   
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    stories = [[NSMutableArray alloc] init];

    //you must then convert the path to a proper NSURL or it won't work
    NSURL *xmlURL = [NSURL URLWithString:URL];

    // here, for some reason you have to use NSClassFromString when trying to alloc NSXMLParser, otherwise you will get an object not found error
    // this may be necessary only for the toolchain
    rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];

    // Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
    [rssParser setDelegate:self];

    // Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
    [rssParser setShouldProcessNamespaces:NO];
    [rssParser setShouldReportNamespacePrefixes:NO];
    [rssParser setShouldResolveExternalEntities:NO];

    [rssParser parse];

    [pool release];
}

从您的评论中,您说您正在后台线程中运行解析器…UIKit不是线程安全的,我怀疑这就是导致您出现问题的原因…尝试在主线程上进行重新加载数据调用,您可以使用NSObjects performSelectorInMainThread来执行此操作

[self performSelectorOnMainThread:@selector(operationComplete) withObject:nil waitUntilDone:false];

parseDidEndDocument是否发生在后台线程中?因为如果它是…UI不是线程安全的…也许你的问题是,你在后台调用UI工具包(不安全),并且在主线程中制作动画…(行为未定义)@Daniel–你实际上可能在这里发现了一些东西。我正在以分离线程的形式运行XML请求。我将更新主要问题,并在“我的测试”标题下的底部添加一些额外的问题。如果您这样做,那么这就是您的问题…UIKit不是线程安全的。。。尝试在主线程中执行重新加载调用刚刚实现了这一点,在进入和退出设置菜单几十次之后,它还没有发生。看起来这个问题现在已经解决了。谢谢这取决于我们谈论的iOS版本。UIKit在iOS 4.0+中是线程安全的。