如何在表视图中实现搜索(使用FRC) [英] How to implement search in a table view (with FRC)

查看:124
本文介绍了如何在表视图中实现搜索(使用FRC)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本原理很简单:只需在表视图控制器中实现< UISearchBarDelegate,UISearchDisplayDelegate> 。这里是足够的教程



诀窍是实现有两个控制器:一个表视图控制器和一个搜索显示控制器。每个控制器都有自己的表视图。因此,两个表视图正在播放:正常表视图和搜索显示表视图。当委托方法有一个UITableView参数,diff表格视图传入,并做相应的不同的事情。



除了基础以外,数据结构成为我的主要挑战。更具体地说,如何过滤和存储搜索结果?我们有三个选项:



A。




  • 正常表格视图的一个FRC


  • 创建用于存储结果的数组属性


  • 使用 filteredArrayWithPredicate 过滤所获取的对象(数组)


  • b
    $ b

    • 正常表格视图的一个FRC


    • 修改FRC的谓词过滤器。 Apple doc指示3个步骤:


      1. 删除FRC缓存(最好不要使用第一个)

      2. 更改谓词

      3. 调用performFetch



    b $ b

    C。



    两个FRC,每个表视图一个。 此热门帖子的接受答案中提供了详细的实施方案






    我认为A是正确的方式。我的理由包括:



    A完成所有的工作。它只需要对具有FRC属性的表视图控制器进行无关紧要的更改。更具体地说,只是在每个委托方法中的两个表视图之间进行差异,并添加一个NSArray属性来存储提取结果。当然,添加过滤代码。



    B有一个潜在的缺点:FRC委托方法会对使用哪个提取请求感到困惑?是一个在搜索之前,或在搜索,或搜索后?虽然可能有解决方案,我不认为它值得的时间,只要解决方案A是工作。



    第二个缺点是,如果我们希望搜索结果随时更改。在搜索栏中的每个单字母用户类型将导致FRC执行Fetch,这是相当昂贵的。



    C通过使用两个FRC避免了B的第一个缺点,出于完全相同的原因。



    其他需要考虑的事项:




    • p>在后台队列中进行过滤。所以当用户在搜索栏中输入时,屏幕不会被阻止,无论你的过滤是多么昂贵。


    • 创建帮助方法以在两个表视图之间进行比较。调用相关代理方法中的帮助方法,这将使代码更清晰。




    表视图。如果有任何错误,请帮助指出。非常感谢。

    解决方案

    我认为有一些关于UITableViews和FRC的概念错误。 FRC只是一个从Core Data获取数据的类,与MOC一起确保它保留数据完整性,即使您有多个选项卡同时访问同一个数据库,每个都执行自己的更新。在幕后,有正在进行的进程,以确保一个选项卡中的更新反映在所有其他选项卡。我实际上说的是有后果,如果你绕过推荐的方法。



    performFetch输出可以存储在缓存中,如果由于某种原因需要执行[tableview reloadData],则会跳过提取。你当然可以编程来获取它的数据从多个来源的tableview,但我没有看到任何理由这样做。如果多个源的唯一原因是在搜索之前跟踪结果,则应该有一种方法来重置谓词,以便FRC获取所有(当前)记录。在我的应用程序的情况下,将所有或所有记录放在搜索栏中,产生一个谓词1 = 1,它获得所有记录。再次,这可能不是在单个视图应用程序相关,但带有多个并发更新的选项卡式应用程序将需要这样做,以确保数据是最新的。


    The basics are simple: just implement <UISearchBarDelegate,UISearchDisplayDelegate> in your table view controller. Here is an adequate tutorial.

    The trick is to realize that there are TWO controllers: a table view controller, and a search display controller. Each controller has its own table view. Hence TWO table views are in play: the normal table view and the search display table view. When delegate methods have a UITableView argument, diff which table view is passed in, and do different things accordingly.

    Beyond above basics, data structure becomes a main challenge for me. More specific, how to filter and store the search results? We have three options:

    A.

    • One FRC for the normal table view

    • Create an array property to store results

    • Use filteredArrayWithPredicate to filter fetched objects (an array)

    • Specify a cache for FRC to store fetched objects in memory to enahnce performance

    B.

    • One FRC for the normal table view

    • Modify FRC's predicate to do the filter. Apple doc instructs 3 steps to do that:

      1. Delete FRC cache (better not to use one in the first place)
      2. Change predicate
      3. Invoke performFetch

    C.

    Two FRC, one for each table view. A detailed implementation is provided in the accepted answer of this popular post


    I think A is the right way to go. My rationale include:

    A does all the job well. And it only requires insignificant changes to a table view controller with FRC property. Being more specific, just diff between the two table views in every delegate methods, and add an NSArray property to store fetch results. And, of course, add the filtering code.

    B has a potential drawback: FRC delegate methods will get confused on which fetch request is being used? Is the one before search, or during search, or after search? Although there might be solution out there, I don't think it worth the time provided that solution A is working.

    The second drawback is that, if we want search results to change on the fly. Every single letter user types in search bar will cause FRC to performFetch, which is rather expensive.

    C avoids B's first drawback by using two FRC, yet it suffers from the second for exactly same reason.

    Other things to consider:

    • Do filtering in a background queue. So when user type in search bar, screen won't get blocked no matter how expensive your filtering is.

    • Create a helper method to diff between the two table views. Call the helper method in relevant delegate methods, which would make code cleaner.

    Above are my understanding of implement search in table view. If there is any mistake, please help point it out. Many thanks.

    解决方案

    I think there are some conceptual errors regarding UITableViews and FRC. The FRC is just a class to get data from Core Data and together with the MOC ensure that it retains data integrity, even if you have a several tabs that access the same database concurrently , each doing their own updates. Behind the scenes there are processes in play to ensure that an update in one tab gets reflected in all the other tabs. What I am actually saying is there are consequences if you bypass the recommended method.

    The performFetch output can be stored in cache and skips fetching if for some reason you need to do a [tableview reloadData]; You can certainly program to get the tableview get its data from multiple sources but I do not see any reason for doing this. If the only reason for multiple sources is to keep track of the results before the search, there should be a way to reset the predicate in order for the FRC to get all the (current) records. In the case of my app, putting all or all records in the searchbar, results in a predicate 1=1 which gets all the records. Again, this may not be that relevant in a single view app, but a tabbed app with a number of concurrent updates will require this to ensure data is current all across.

    这篇关于如何在表视图中实现搜索(使用FRC)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆