【问题标题】:Realm Swift background searchRealm Swift 后台搜索
【发布时间】:2016-04-06 08:46:02
【问题描述】:

我的应用中有一个领域数据库,其中包含约 2000 个用户的列表。

表格视图显示这些用户,搜索栏允许过滤它们(每个用户的 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)
        })
    })
}

【问题讨论】:

    标签: swift realm background-thread


    【解决方案1】:

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

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

    除此之外,我建议对 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)
            })
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多