对于在当前显示的iphone tableview中更新数据的长时间运行操作,最佳做法是什么?

时间:2022-02-25 19:34:14

Background:

I have a tableview displaying about 8 sections each backed with my own PlaceList class representing a list of objects (the implementation uses an NSMutableArray). There are around 200 objects in total. Each section corresponds to how far away the object is from the current location (e.g. within 1 mile, within 10, 25, 50...etc).

我有一个tableview显示大约8个部分,每个部分都支持我自己的PlaceList类,表示对象列表(实现使用NSMutableArray)。总共有大约200个对象。每个部分对应于物体离当前位置有多远(例如,在1英里内,在10,25,50 ......之内)。

Every now and then, I need to respond to asynchronous notifications from CoreLocation that require me to recalculate which section each object belongs in, update the distance for each object (which is displayed in each cell), and also resort each list, then reload the table view. I also do this operation in viewWillAppear.

偶尔,我需要响应来自CoreLocation的异步通知,这些通知要求我重新计算每个对象所属的部分,更新每个对象的距离(显示在每个单元格中),并且还要求每个列表,然后重新加载表视图。我也在viewWillAppear中执行此操作。

Within the operation that performs the update (a method on PlaceList) I've used @synchronized(self) in case it gets invoked from more than one thread by the OS (I don't use another thread for it myself at present). However, currently this operation results in the UI feeling 'frozen' from time to time, so I'm looking at ways to do it in its own thread.

在执行更新的操作(PlaceList上的方法)中,我使用了@synchronized(self),以防它被OS从多个线程调用(我目前不使用另一个线程)。但是,目前这个操作导致UI不时感觉“冻结”,所以我正在寻找在自己的线程中做到这一点的方法。

Question:

  • What's the best way to do this kind of long running operation on the data backing a table view? As far as I can see it is not safe to spin off a background thread to do the operation, as even if I use performSelector to reload the table view on the main thread when done, it is still possible that the user will tap a cell while the operation is running and the data is not consistent with the display. And adding any kind of locking would just defeat the purpose.

    在支持表视图的数据上执行此类长时间运行操作的最佳方法是什么?据我所知,剥离后台线程来执行操作是不安全的,因为即使我在完成时使用performSelector重新加载主线程上的表视图,用户仍然可能会点击一个单元格操作正在运行且数据与显示不一致。并且添加任何类型的锁定都会破坏目的。

  • Do the UI and CoreLocation locationManager send their notifications on the same thread, i.e. can I safely dispense with the @synchronized(self) on the PlaceList?

    UI和CoreLocation locationManager是否在同一个线程上发送通知,即我可以安全地免除PlaceList上的@synchronized(self)吗?

1 个解决方案

#1


Here's my understanding of your problem. You have a large list of data, and at some point it will become invalid. In order to get it valid again, you have to do some processing before you can repaint the table.

这是我对你的问题的理解。您有大量数据,在某些时候它将变为无效。为了使其再次有效,您必须先进行一些处理才能重新绘制表格。

If this is correct, here's a few options.

如果这是正确的,这里有几个选项。

1) Double buffer your data. As long as you are displaying something that "was" correct, the user can interact with it just fine. When you get your trigger to reprocess your data, work on it in the background with a copy, and when it's ready to redraw completely, update. That update may be abrupt and large, but the data displayed will always be correct, or at least sane, and the UI continues to function and doesn't scare the user.

1)双倍缓冲数据。只要您显示“是”正确的内容,用户就可以很好地与它进行交互。当您获得重新处理数据的触发器时,请在后台使用副本处理它,并且当它准备好完全重绘时,请更新。该更新可能是突然的和大的,但显示的数据将始终是正确的,或者至少是理智的,并且UI继续运行并且不会吓到用户。

This largely avoids the threading issue since the notifications aren't modifying data and trying to show it at the same time.

这在很大程度上避免了线程问题,因为通知不会修改数据并尝试同时显示它。

AFAIK, the Facebook application seems to do this, as well as TwitterFon. At least that's how it feels. Hard to say for sure.

AFAIK,Facebook应用程序似乎这样做,以及TwitterFon。至少那是它的感觉。很难说肯定。

2) Loading screen! Not fun, but it works. When you know the data is bad, throw up a semitransparent panel and tell the user to hang on a bit.

2)加载屏幕!不好玩,但它有效。当你知道数据不好时,抛出一个半透明的面板并告诉用户稍微停下来。

It really boils down to update now, or later. You have to decide what trade-offs make the most sense in your application.

它真的归结为现在更新或更晚。您必须决定在您的应用程序中最有意义的权衡。

#1


Here's my understanding of your problem. You have a large list of data, and at some point it will become invalid. In order to get it valid again, you have to do some processing before you can repaint the table.

这是我对你的问题的理解。您有大量数据,在某些时候它将变为无效。为了使其再次有效,您必须先进行一些处理才能重新绘制表格。

If this is correct, here's a few options.

如果这是正确的,这里有几个选项。

1) Double buffer your data. As long as you are displaying something that "was" correct, the user can interact with it just fine. When you get your trigger to reprocess your data, work on it in the background with a copy, and when it's ready to redraw completely, update. That update may be abrupt and large, but the data displayed will always be correct, or at least sane, and the UI continues to function and doesn't scare the user.

1)双倍缓冲数据。只要您显示“是”正确的内容,用户就可以很好地与它进行交互。当您获得重新处理数据的触发器时,请在后台使用副本处理它,并且当它准备好完全重绘时,请更新。该更新可能是突然的和大的,但显示的数据将始终是正确的,或者至少是理智的,并且UI继续运行并且不会吓到用户。

This largely avoids the threading issue since the notifications aren't modifying data and trying to show it at the same time.

这在很大程度上避免了线程问题,因为通知不会修改数据并尝试同时显示它。

AFAIK, the Facebook application seems to do this, as well as TwitterFon. At least that's how it feels. Hard to say for sure.

AFAIK,Facebook应用程序似乎这样做,以及TwitterFon。至少那是它的感觉。很难说肯定。

2) Loading screen! Not fun, but it works. When you know the data is bad, throw up a semitransparent panel and tell the user to hang on a bit.

2)加载屏幕!不好玩,但它有效。当你知道数据不好时,抛出一个半透明的面板并告诉用户稍微停下来。

It really boils down to update now, or later. You have to decide what trade-offs make the most sense in your application.

它真的归结为现在更新或更晚。您必须决定在您的应用程序中最有意义的权衡。