What are good practices for asynchronously pulling large amounts of XML from a RESTful service into a Core Data store, and from this store, populating a UITableView
on the fly?
什么是将大量XML从RESTful服务异步提取到Core Data存储中的良好实践,以及从这个存储中随时填充UITableView的好方法?
I'm thinking of using libxml2's xmlParseChunk()
function to parse chunks of incoming XML and translate a node and its children into the relevant managed objects, as nodes come in.
我正在考虑使用libxml2的xmlParseChunk()函数来解析传入XML的块,并在节点进入时将节点及其子节点转换为相关的托管对象。
At the same time that these XML nodes are turned into managed objects, I want to generate UITableView
rows, in turn. Say, 50 rows at a time. Is this realistic?
在将这些XML节点转换为托管对象的同时,我想依次生成UITableView行。比如说,一次50行。这是现实的吗?
In your experience, what do you do to accomplish this task, to maintain performance and handle, potentially, thousands of rows? Are there different, simpler approaches that work as well or better?
根据您的经验,您如何完成此任务,以维护性能并处理数千行?是否有不同的,更简单的方法可以运行得更好或更好?
3 个解决方案
#1
14
Sure, this is a pretty standard thing. The easiest solution is to do the loading in a background thread on one MOC, and have the UI running on the main thread with its own MOC. Whenever you get a chunk of data you want to have appear (say 50 entries), you have the background MOCsave:
.
当然,这是一个非常标准的事情。最简单的解决方案是在一个MOC上的后台线程中加载,并在主线程上运行UI并使用自己的MOC。每当你想要出现一大块数据时(例如50个条目),你就有了背景MOCsave:。
Assuming you have the foreground MOC rigged to merge changes (via mergeChangesFromContextDidSaveNotification:
) then whenever you save the background MOC the foreground MOC will get all of those changes. Assuming you are using NSFetchedResultsController it has delegate methods to cope with changes in its MOC, and if you are using Apple's sample code then you probably already have everything setup correctly.
假设你有前台MOC操纵合并更改(通过mergeChangesFromContextDidSaveNotification :)然后每当你保存背景MOC时,前台MOC将获得所有这些更改。假设您正在使用NSFetchedResultsController,它具有委托方法来处理其MOC中的更改,如果您使用Apple的示例代码,那么您可能已经正确设置了所有内容。
In general CoreData is going to be faster than anything you roll yourself unless you really know what you are doing and are willing to spend a ton of time tuning for your specific case. The biggest thing you can do is make sure that slow things (like XML processing and synchronous flash I/O caused by save:
) are not on the main thread blocking user interaction.
一般来说,除非你真的知道自己在做什么,并且愿意花费大量时间来调整你的特定情况,否则CoreData会比你自己动手的任何东西都要快。您可以做的最重要的事情是确保缓慢的事情(如由处理引起的XML处理和同步闪存I / O)不在阻止用户交互的主线程上。
#2
2
Joe Hewitt (Facebook app developer) has release much of his code as open-source. It is called Three20. There is a class there that is great for fetching internet data and populating it into a table, without the need for the data beforehand. The classes used for this are called TTTableViewController and TTTableViewDataSource.
Joe Hewitt(Facebook应用程序开发人员)已将其大部分代码发布为开源代码。它被称为Three20。那里有一个类非常适合获取Internet数据并将其填充到表中,而不需要事先获取数据。用于此的类称为TTTableViewController和TTTableViewDataSource。
From here, it would not be much of a stretch to store as CoreData, just subclass the classes as you see fit with the supplied hooks.
从这里开始,将CoreData存储起来并不是一个很大的延伸,只需按照您认为适合的钩子对类进行子类化。
If you are worried about too much data, 50 at a time does sound reasonable. These classes have a built in "More" button to help you out.
如果您担心数据太多,一次50个听起来合理。这些类有一个内置的“更多”按钮来帮助你。
From the Three20 readme:
来自Three20自述文件:
Internet-aware table view controllers
TTTableViewController and TTTableViewDataSource help you to build tables which load their content from the Internet. Rather than just assuming you have all the data ready to go, like UITableView does by default, TTTableViewController lets you communicate when your data is loading, and when there is an error or nothing to display. It also helps you to add a "More" button to load the next page of data, and optionally supports reloading the data by shaking the device.支持Internet的表视图控制器TTTableViewController和TTTableViewDataSource可帮助您构建从Internet加载其内容的表。默认情况下,UTableViewController可以让您在加载数据时进行通信,并在出现错误或无法显示任何内容时,而不仅仅假设您已准备好所有数据。它还可以帮助您添加“更多”按钮以加载下一页数据,并可选择通过摇动设备来重新加载数据。
#3
0
No one has mentioned RestKit yet? My friends ... seriously, you have to check this out. If you are doing anything with REST on iOS (and now on OS X) and particularly if you're wanting to work with Core Data ... PLEASE have a look at RestKit. I've saved countless hours implementing some pretty complex data synchronization between a server and my Core Data models on iOS. RestKit made it so damned easy, it almost makes you sick.
还没有人提到过RestKit吗?我的朋友......说真的,你必须检查一下。如果你在iOS上(现在在OS X上)使用REST做任何事情,特别是如果你想使用Core Data ...请看看RestKit。我在服务器和iOS上的核心数据模型之间实现了一些非常复杂的数据同步,从而节省了不少时间。 RestKit让它太容易了,它几乎让你生病了。
#1
14
Sure, this is a pretty standard thing. The easiest solution is to do the loading in a background thread on one MOC, and have the UI running on the main thread with its own MOC. Whenever you get a chunk of data you want to have appear (say 50 entries), you have the background MOCsave:
.
当然,这是一个非常标准的事情。最简单的解决方案是在一个MOC上的后台线程中加载,并在主线程上运行UI并使用自己的MOC。每当你想要出现一大块数据时(例如50个条目),你就有了背景MOCsave:。
Assuming you have the foreground MOC rigged to merge changes (via mergeChangesFromContextDidSaveNotification:
) then whenever you save the background MOC the foreground MOC will get all of those changes. Assuming you are using NSFetchedResultsController it has delegate methods to cope with changes in its MOC, and if you are using Apple's sample code then you probably already have everything setup correctly.
假设你有前台MOC操纵合并更改(通过mergeChangesFromContextDidSaveNotification :)然后每当你保存背景MOC时,前台MOC将获得所有这些更改。假设您正在使用NSFetchedResultsController,它具有委托方法来处理其MOC中的更改,如果您使用Apple的示例代码,那么您可能已经正确设置了所有内容。
In general CoreData is going to be faster than anything you roll yourself unless you really know what you are doing and are willing to spend a ton of time tuning for your specific case. The biggest thing you can do is make sure that slow things (like XML processing and synchronous flash I/O caused by save:
) are not on the main thread blocking user interaction.
一般来说,除非你真的知道自己在做什么,并且愿意花费大量时间来调整你的特定情况,否则CoreData会比你自己动手的任何东西都要快。您可以做的最重要的事情是确保缓慢的事情(如由处理引起的XML处理和同步闪存I / O)不在阻止用户交互的主线程上。
#2
2
Joe Hewitt (Facebook app developer) has release much of his code as open-source. It is called Three20. There is a class there that is great for fetching internet data and populating it into a table, without the need for the data beforehand. The classes used for this are called TTTableViewController and TTTableViewDataSource.
Joe Hewitt(Facebook应用程序开发人员)已将其大部分代码发布为开源代码。它被称为Three20。那里有一个类非常适合获取Internet数据并将其填充到表中,而不需要事先获取数据。用于此的类称为TTTableViewController和TTTableViewDataSource。
From here, it would not be much of a stretch to store as CoreData, just subclass the classes as you see fit with the supplied hooks.
从这里开始,将CoreData存储起来并不是一个很大的延伸,只需按照您认为适合的钩子对类进行子类化。
If you are worried about too much data, 50 at a time does sound reasonable. These classes have a built in "More" button to help you out.
如果您担心数据太多,一次50个听起来合理。这些类有一个内置的“更多”按钮来帮助你。
From the Three20 readme:
来自Three20自述文件:
Internet-aware table view controllers
TTTableViewController and TTTableViewDataSource help you to build tables which load their content from the Internet. Rather than just assuming you have all the data ready to go, like UITableView does by default, TTTableViewController lets you communicate when your data is loading, and when there is an error or nothing to display. It also helps you to add a "More" button to load the next page of data, and optionally supports reloading the data by shaking the device.支持Internet的表视图控制器TTTableViewController和TTTableViewDataSource可帮助您构建从Internet加载其内容的表。默认情况下,UTableViewController可以让您在加载数据时进行通信,并在出现错误或无法显示任何内容时,而不仅仅假设您已准备好所有数据。它还可以帮助您添加“更多”按钮以加载下一页数据,并可选择通过摇动设备来重新加载数据。
#3
0
No one has mentioned RestKit yet? My friends ... seriously, you have to check this out. If you are doing anything with REST on iOS (and now on OS X) and particularly if you're wanting to work with Core Data ... PLEASE have a look at RestKit. I've saved countless hours implementing some pretty complex data synchronization between a server and my Core Data models on iOS. RestKit made it so damned easy, it almost makes you sick.
还没有人提到过RestKit吗?我的朋友......说真的,你必须检查一下。如果你在iOS上(现在在OS X上)使用REST做任何事情,特别是如果你想使用Core Data ...请看看RestKit。我在服务器和iOS上的核心数据模型之间实现了一些非常复杂的数据同步,从而节省了不少时间。 RestKit让它太容易了,它几乎让你生病了。