【问题标题】:reloadData not being called immediately (an NSXMLParserDelegate dilemma)reloadData 没有被立即调用(一个 NSXMLParserDelegate 困境)
【发布时间】:2012-10-01 15:57:57
【问题描述】:

我继承了一些我正在尝试调试的该死的糟糕代码。

我正在使用 NSXMLParser 解析 RSS 提要。在 parser:didEndElement:etc: 中,当每个新项目出现时,我触发另一个调用 UITableView 的 reloadData 方法的方法。但是,调用 reloadData 方法时不会调用它们,而是稍后...在 parserDidEndDocument: ...之后它们会立即触发。

似乎 reloadData 请求在某处排队,在解析线程上阻塞。

如何在我告诉它时强制 reloadData 触发,而不是在它想要的时候触发。我的问题是,因为它只在所有新闻项目都加载后才会重新加载——而且有很多——所以 UI 体验不是最理想的。

【问题讨论】:

    标签: ios uitableview nsxmlparser reloaddata


    【解决方案1】:

    你的猜想是正确的。只有当程序控制返回到主运行循环时,才对用户界面进行更新。 NSXMLParser 但是完全同步工作:parse 方法解析整个 XML 数据(调用委托函数等)并仅在解析完成后返回。因此,在 parser:didEndElement:... 中调用 reloadData 并没有立即可见的效果。

    如果解析您的 XML 数据确实需要太多时间,以至于您不能在 parse 方法返回时调用 reloadData,您必须将解析操作移至单独的线程:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [myParser parse];
    });
    

    dispatch_async 立即返回并在后台线程中完成解析。 因此,委托方法也会在后台线程上调用。由于 UI 的更新只能在主线程上完成,您可以在 parser:didEndElement:...:

    YourType newObject = ... // create new object from XML data
    dispatch_async(dispatch_get_main_queue(), ^{
        // assuming that self.dataArray is your data source array for the table view 
        int newRow = [self.dataArray count]; // row number for new object
        [self.dataArray addObject:newObject]; // add to your data source
        // insert row in table view:
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:newRow inSection:0];
        [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                              withRowAnimation:UITableViewRowAnimationAutomatic];
    });
    

    使用insertRowsAtIndexPaths 而不是reloadData 应该可以提供“更流畅”的动画UI更新。

    我确实希望我的示例代码中没有太多的语法错误,并且它会有所帮助。否则请随时询问。

    【讨论】:

    • 非常感谢您,Martin R!我一定会试一试的。
    猜你喜欢
    • 2015-03-30
    • 2011-09-01
    • 2020-03-28
    • 2016-02-24
    • 1970-01-01
    • 2017-02-11
    • 1970-01-01
    • 2012-01-28
    • 1970-01-01
    相关资源
    最近更新 更多