本地存储coredata和realm

    技术2025-07-08  15

    软件产品的两种形态

    client-server,客户端,本地存储用的较多browser-server,网站,服务器存储用的多,例如mysql

    IOS本地存储数据库

    userdefaults 存储轻量级数据core data 学习成本高,代码较多,速度没有realm快realm 第三方功能包

    realm

    // 定义模型的做法和定义常规 Swift 类的做法类似,需要继承 class Dog: Object { @objc dynamic var name = "" @objc dynamic var age = 0 } class Person: Object { @objc dynamic var name = "" @objc dynamic var picture: Data? = nil // 支持可空值 let dogs = List<Dog>() } // 像常规 Swift 对象一样使用 let myDog = Dog() myDog.name = "Rex" myDog.age = 1 print("name of dog: \(myDog.name)") // 获取默认的 Realm 数据库 let realm = try! Realm() // 检索 Realm 数据库,找到小于 2 岁 的所有狗狗 let puppies = realm.objects(Dog.self).filter("age < 2") puppies.count // => 0 因为目前还没有任何狗狗被添加到了 Realm 数据库中 // 数据存储十分简单 try! realm.write { realm.add(myDog) } // 检索结果会实时更新 puppies.count // => 1 // 可以在任何一个线程中执行检索、更新操作 DispatchQueue(label: "background").async { autoreleasepool { let realm = try! Realm() let theDog = realm.objects(Dog.self).filter("age == 1").first try! realm.write { theDog!.age = 3 } } } 增 let user = User() user.name = "gaibb" user.age = 21 do { let realm = try Realm() try realm.write({ realm.add(user) }) } catch{ print(error) } print(Realm.Configuration.defaultConfiguration.fileURL) 查 objects方法返回一个Results< Element>类型数据 var todos: Results<Todo>? todos = realm.objects(Todo.self) 改:直接对获得的Results< Element>类型数据修改 do { try realm.write({ todos![row].name = name }) } catch { print(error) } 删 do { try realm.write({ realm.delete(todos![indexPath.row]) }) } catch { print(error) }

    条件搜索

    / 使用断言字符串来查询 var tanDogs = realm.objects(Dog.self).filter("color = 'tan' AND name BEGINSWITH 'B'") // 使用 NSPredicate 来查询 let predicate = NSPredicate(format: "color = %@ AND name BEGINSWITH %@", "tan", "B") tanDogs = realm.objects(Dog.self).filter(predicate) 比较操作数可以是属性名,也可以是常量。但至少要有一个操作数是属性名;比较操作符 ==、<=、<、>=、>、!= 和 BETWEEN 支持 Int、Int8、Int16、Int32、Int64、Float、Double 以及 Date 这几种属性类型,例如 age == 45;比较是否相同:== 和 !=,例如,Results().filter(“company == %@”, company);比较操作符 == 和 != 支持布尔属性; 对于 String 和 Data 属性而言,支持使用 ==、!=、BEGINSWITH、CONTAINS 和 ENDSWITH 操作符,例如 name CONTAINS ‘Ja’;对于 String 属性而言,LIKE 操作符可以用来比较左端属性和右端表达式:? 和 * 可用作通配符,其中 ? 可以匹配任意一个字符,* 匹配 0 个及其以上的字符。例如:value LIKE ‘?bc*’ 可以匹配到诸如 “abcde” 和 “cbc” 之类的字符串;字符串的比较忽略大小写,例如 name CONTAINS[c] ‘Ja’。请注意,只有 “A-Z” 和 “a-z” 之间的字符大小写会被忽略。[c] 修饰符可以与 [d] 修饰符结合使用;字符串的比较忽略变音符号,例如 name BEGINSWITH[d] ‘e’ 能够匹配到 étoile。这个修饰符可以与 [c] 修饰符结合使用。(这个修饰符只能够用于 Realm 所支持的字符串子集:参见当前的限制一节来了解详细信息。)Realm 支持以下组合操作符:“AND”、“OR” 和 “NOT”,例如 name BEGINSWITH ‘J’ AND age >= 32;包含操作符:IN,例如 name IN {‘Lisa’, ‘Spike’, ‘Hachi’};空值比较:==、!=,例如 Results().filter(“ceo == nil”)。请注意,Realm 将 nil 视为一种特殊值,而不是某种缺失值;这与 SQL 不同,nil 等同于自身;ANY 比较,例如 ANY student.age < 21;List 和 Results 属性支持聚集表达式:@count、@min、@max、@sum 和 @avg,例如 realm.objects(Company.self).filter(“employees.@count > 5”) 可用以检索所有拥有 5 名以上雇员的公司。支持子查询,不过存在以下限制: @count 是唯一一个能在 SUBQUERY 表达式当中使用的操作符;SUBQUERY(…).@count 表达式只能与常量相比较;

    排序

    请注意,sorted(byKeyPath:) 和 sorted(byProperty:) 不支持 将多个属性用作排序基准,此外也无法链式排序(只有最后一个 sorted 调用会被使用)。 如果要对多个属性进行排序,请使用 sorted(by:) 方法,然后向其中输入多个 SortDescriptor 对象。 // 对颜色为棕黄色、名字以 "B" 开头的狗狗进行排序 let sortedDogs = realm.objects(Dog.self).filter("color = 'tan' AND name BEGINSWITH 'B'") .sorted(byKeyPath: "name") class Person: Object { @objc dynamic var name = "" @objc dynamic var dog: Dog? } class Dog: Object { @objc dynamic var name = "" @objc dynamic var age = 0 } let dogOwners = realm.objects(Person.self) let ownersByDogAge = dogOwners.sorted(byKeyPath: "dog.age")
    Processed: 0.014, SQL: 9