草庐IT

swift - Realm Swift 后台搜索

coder 2023-09-15 原文

我的应用程序中有一个 Realm 数据库,其中包含约 2000 名用户的列表。

一个表格 View 显示这些用户,一个搜索栏允许过滤他们(每个用户的 6 个不同属性)。 此操作阻塞了 UI,因此我将其置于后台线程中。

现在好多了,但我不能 100% 确定这是最好的方法。

如果您有更好的解决方案,您能否提出其他解决方案?

这是我使用的示例代码:

func filterUsers(searchText:String,completion: (result: Array<User>) -> ()){

    var IIDS = Array<String>()

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in

        let predicate1 = NSPredicate(format: "firstName contains[c] %@", searchText)
        let predicate2 = NSPredicate(format: "lastName contains[c] %@", searchText)

        let bgRealm = try! Realm()
        bgRealm.beginWrite()

        //Filter the whole list of users
        var results = Array(bgRealm.objects(User)).filter {
            //One user object by one
            let usr:User = $0
            //Reset the value by default
            usr.searchResultField = ""

            if predicate1.evaluateWithObject(usr) {
                usr.searchResultField = "firstNameORlastName"
                return true
            }
            else if predicate2.evaluateWithObject(usr) {
                usr.searchResultField = "IID"
            }

            return false
        };

        try! bgRealm.commitWrite()

        for usr in results {
            IIDS.append("'\(usr.IID)'")
        }

        results.removeAll()

        dispatch_async(dispatch_get_main_queue(), { () -> Void in

            let realm = try! Realm()
            let foundUsers = Array(realm.objects(User).filter("IID IN {\(IIDS.joinWithSeparator(","))}"))
            IIDS.removeAll()
            completion(result: foundUsers)
        })
    })
}

最佳答案

将对象全部拉入内存后过滤对象(通过将Results 转换为Array)。如果让 Realm 处理过滤,您将获得更好的性能。为此,您需要能够通过谓词进行所有查询,您可以将这些谓词组合成一个 OR 复合谓词。

此外,我会避免将匹配字段存储在对象中以分离关注点,因为值是 transient 的。只有当这些对象保存在内存中时才需要它们。

除此之外,我建议为 IID 使用主键,然后通过一个对象检索另一个对象,而不是构建一个包含所有 ID 的巨大谓词。

总而言之,这就是我解决这个问题的方式:

func filterUsers(searchText:String, completion: (result: Array<(user: User, field: String)>) -> ()) {   
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
        var predicates = [
          "firstName": NSPredicate(format: "firstName contains[c] %@", searchText)
          "lastName":  NSPredicate(format: "lastName contains[c] %@", searchText)
        ]
        let compoundPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: Array(predicates.values))

        let bgRealm = try! Realm()

        // Filter the whole list of users
        let results = bgRealm.objects(User).filter(compoundPredicate)

        // Find out which field is matching
        let idsAndFields: [(IID: String, field: String)] = results.flatMap {
            for (field, predicate) in predicates {
                if predicate.evaluateWithObject($0) {
                    return (IID: $0.IID, field: field)
                }
            }
            return nil
        }

        dispatch_async(dispatch_get_main_queue()) {
            let realm = try! Realm()
            let result = idsAndFields.flatMap {
                if let user = realm.objectForPrimaryKey($0.IID) {
                    return (user: user, field: $0.field)
                } else {
                    return nil
                }
            }
            completion(result: result)
        })
    }
}

关于swift - Realm Swift 后台搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36445944/

有关swift - Realm Swift 后台搜索的更多相关文章

  1. ruby-on-rails - Nokogiri:使用 XPath 搜索 <div> - 2

    我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll

  2. ruby - 如何在 ruby​​ 中运行后台线程? - 2

    我是ruby​​的新手,我认为重新构建一个我用C#编写的简单聊天程序是个好主意。我正在使用Ruby2.0.0MRI(Matz的Ruby实现)。问题是我想在服务器运行时为简单的服务器命令提供I/O。这是从示例中获取的服务器。我添加了使用gets()获取输入的命令方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程。require'socket'#Getsocketsfromstdlibserver=TCPServer.open(2000)#Sockettolistenonport2000defcommandsx=1whilex==1exitProgram=gets.chomp

  3. ruby - 如何搜索有用的 ruby - 2

    寻找有用的ruby的好网站是什么? 最佳答案 AgileWebDevelopment列出插件(虽然不是ruby​​gems,我不确定为什么),并允许人们对它们进行评级。RubyToolbox按类别列出gem并比较它们的受欢迎程度。Rubygems有一个搜索框。StackOverflow对最有用的rails插件和ruby​​gems有疑问。 关于ruby-如何搜索有用的ruby,我们在StackOverflow上找到一个类似的问题: https://stacko

  4. ruby - 如何搜索、递增和替换 Ruby 字符串中的整数子字符串? - 2

    我有很多这样的文档:foo_1foo_2foo_3bar_1foo_4...我想通过获取foo_[X]的所有实例并将它们中的每一个替换为foo_[X+1]来转换它们。在这个例子中:foo_2foo_3foo_4bar_1foo_5...我可以用gsub和一个block来做到这一点吗?如果不是,最干净的方法是什么?我真的在寻找一个优雅的解决方案,因为我总是可以暴力破解它,但我觉得有一些正则表达式技巧值得学习。 最佳答案 我(完全)不懂Ruby,但类似这样的东西应该可以工作:"foo_1foo_2".gsub(/(foo_)(\d+)/

  5. ruby - Ruby 中的必应搜索 API - 2

    我读了"BingSearchAPI-QuickStart"但我不知道如何在Ruby中发出这个http请求(Weary)如何在Ruby中翻译“Stream_context_create()”?这是什么意思?"BingSearchAPI-QuickStart"我想使用RubySDK,但我发现那些已被弃用前(Rbing)https://github.com/mikedemers/rbing您知道Bing搜索API的最新包装器(仅限Web的结果)吗? 最佳答案 好吧,经过一个小时的挫折,我想出了一个办法来做到这一点。这段代码很糟糕,因为它是

  6. Ruby#index 方法 VS 二进制搜索 - 2

    给定一个元素和一个数组,Ruby#index方法返回元素在数组中的位置。我使用二进制搜索实现了我自己的索引方法,期望我的方法会优于内置方法。令我惊讶的是,内置的在实验中的运行速度大约是我的三倍。有Rubyist知道原因吗? 最佳答案 内置#indexisnotabinarysearch,这只是一个简单的迭代搜索。但是,它是用C而不是Ruby实现的,因此自然可以快几个数量级。 关于Ruby#index方法VS二进制搜索,我们在StackOverflow上找到一个类似的问题:

  7. ruby - 使用 Ransack 搜索枚举字段 - 2

    我有一个表,'jobs'和一个枚举字段'status'。status具有以下枚举集:enumstatus:[:draft,:active,:archived]使用ransack,我如何过滤表,比如说,所有事件记录? 最佳答案 你可以像这样在模型中声明自己的掠夺者:ransacker:status,formatter:proc{|v|statuses[v]}do|parent|parent.table[:status]end然后您可以使用默认的搜索语法_eq来检查相等性,如下所示:Model.ransack(status_eq:'ac

  8. ruby-on-rails - Rails 4 postgres 全文搜索错误(范围) - 2

    我一直在使用postgres关注railscast的全文搜索,但我不断收到以下错误#的未定义局部变量或方法“作用域”我关注了railscast确切地。我安装了所有正确的gem。(pg_search,pg)。这是我的代码文章Controller(我在这里也使用acts_as_taggable)defindex@articles=Article.text_search(params[:query]).page(params[:page]).per_page(3)ifparams[:tag]@articles=Article.tagged_with(params[:tag])else@art

  9. ruby - 如何使用部分字符串搜索数组并返回索引? - 2

    我想使用部分字符串搜索数组,然后获取找到该字符串的索引。例如:a=["Thisisline1","Wehaveline2here","andfinallyline3","potato"]a.index("potato")#thisreturns3a.index("Wehave")#thisreturnsnil使用a.grep将返回完整的字符串,使用a.any?将返回正确的true/false语句,但都不会返回匹配的索引找到了,或者至少我不知道该怎么做。我正在编写一段代码,该代码读取文件、查找特定header,然后返回该header的索引,以便它可以将其用作future搜索的偏移量。如果

  10. ruby-on-rails - 自动完成搜索的 Rails 实现 - 2

    我不确定如何为我的搜索功能添加自动完成表单。"get"do%>nil%>我有一个具有自定义操作的Controllerdefquery@users=Search.user(params[:query])@article=Search.article(params[:query])end模型如下:defself.user(search)ifsearchUser.find(:all,:conditions=>['first_nameLIKE?',"%#{search}%"])elseUser.find(:all)endenddefself.article(search)ifsearchArt

随机推荐