К сожалению, я на самом деле не использовать IOS версию, но я использовать Android версии, которая изо дня в день является все больше и больше аналогичны в своем наборе функций для iOS-версии, и они имеют один и тот же core
, и они ближе к обеспечению того же унифицированного поведения через object-store
.
Большая часть этого ответа будет основываться на документах Swift API. (Игровой мир Свифт 2.6.1)
Realm по умолчанию объекта магазин. Технически он хранит свои данные в схеме, где схема определяется классами, как
// from https://realm.io/docs/swift/latest/#models
class Person: Object {
dynamic var name = ""
dynamic var birthdate = NSDate(timeIntervalSince1970: 1)
let dogs = List<Dog>()
}
Теперь, что интересно о Realm является то, что она не является реляционной базой данных; он сохраняет объекты напрямую. Фактически, объекты, управляемые Realm (aka, полученные с помощью запроса в Realm или вновь созданный объект, созданный Realm), отображаются непосредственно в основной файл Realm и не копируют данные в поля, а Accessors непосредственно считывают и записывают в файл Realm.
Этот «прямой доступ» приводит к тому, что все данные загружаются только при доступе (ленивая оценка), поэтому кеширование управляемых объектов не требуется (!).
Все записи являются транзакционными. Вне транзакций управляемые объекты RealmObject не могут быть изменены.
Между вашими объектами, вы можете иметь отношения (ссылки):
// from https://realm.io/docs/swift/latest/#relationships
class Dog: Object {
// ... other property declarations
dynamic var owner: Person? // to-one relationships must be optional
}
class Person: Object {
// ... other property declarations
let dogs = List<Dog>() // to-many relationship
}
Любые отношения (к-одному, ко-многим) имеет соответствующие им backlink
, который можно определить как " объекты, которые связаны с этим объектом ".
// from https://realm.io/docs/swift/latest/#relationships
class Dog: Object {
dynamic var name = ""
dynamic var age = 0
let owners = LinkingObjects(fromType: Person.self, property: "dogs")
}
управляемые объекты Realm являются «живые, неизменные представления данных» (от here), которые мутировать на месте, и вы получите уведомление об изменении о его через notification token
(от here). То же самое относится к любому управляемому RealmObject, но также результаты запроса.
Значение, результаты запроса автоматически асинхронно оцениваются, и только элементы, к которым обращаются по заданному индексу, считываются из базы данных в ленивом порядке! Поэтому разбиение на страницы не требуется.
Любая запись в любом потоке автоматически отправляет уведомление потокам, связанным с циклом запуска, и результаты запроса автоматически обновляются, и вызывается прослушиватель изменений (блок уведомлений).
// from https://realm.io/docs/swift/latest/#collection-notifications
override func viewDidLoad() {
super.viewDidLoad()
let realm = try! Realm()
let results = realm.objects(Person.self).filter("age > 5")
// Observe Results Notifications
notificationToken = results.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in
guard let tableView = self?.tableView else { return }
switch changes {
case .initial:
// Results are now populated and can be accessed without blocking the UI
tableView.reloadData()
break
case .update(_, let deletions, let insertions, let modifications):
// Query results have changed, so apply them to the UITableView
tableView.beginUpdates()
tableView.insertRows(at: insertions.map({ IndexPath(row: $0, section: 0) }),
with: .automatic)
tableView.deleteRows(at: deletions.map({ IndexPath(row: $0, section: 0)}),
with: .automatic)
tableView.reloadRows(at: modifications.map({ IndexPath(row: $0, section: 0) }),
with: .automatic)
tableView.endUpdates()
break
case .error(let error):
// An error occurred while opening the Realm file on the background worker thread
fatalError("\(error)")
break
}
}
}
deinit {
notificationToken?.stop()
}
Наиболее хорошо известное ограничение в том, что RealmObjects, RealmResults и Сферы не могут быть переданы между потоками. (Другие ограничения: here).
A RealmObject/RealmResults/Realm для данного потока может быть доступен только в потоке, где был открыт его соответствующий экземпляр Realm (см. here). (Исключением являются RealmObjects, отправленные между потоками с использованием ThreadSafeReference
, см. here).
Следовательно, фоновые потоки требуют своего собственного экземпляра Realm, обычно обернутого в autoreleasepool
, см. here.
// from https://realm.io/docs/swift/latest/#using-a-realm-across-threads
DispatchQueue(label: "background").async {
autoreleasepool {
// Get realm and table instances for this thread
let realm = try! Realm()
// Break up the writing blocks into smaller portions
// by starting a new transaction
for idx1 in 0..<1000 {
realm.beginWrite()
// Add row via dictionary. Property order is ignored.
for idx2 in 0..<1000 {
realm.create(Person.self, value: [
"name": "\(idx1)",
"birthdate": Date(timeIntervalSince1970: TimeInterval(idx2))
])
}
// Commit the write transaction
// to make this data available to other threads
try! realm.commitWrite()
}
}
}
увидеть это https://realm.io/news/realm-object-centric-present-day-database-mobile-applications/ –
Это объект базы данных. –