В этой статье я хотел бы немного подробнее рассказать о возможностях Core Data. Эта статья продолжение .
Я очень надеюсь, что мне удастся донести мысль о том, что Core Data — это не одна из многих реляционных баз данных, а очень мощный инструмент, способный стать неотъемлемым оружием в арсенале любого уважающего себя iOS-разработчика.
Что ж, начнем! Сегодня мы рассмотрим работу с двумя NSManageObjectContext и NSFetchedResultsController.
Два NSManageObjectContext и зачем они нужны?
Если ваше приложение активно использует какой-то API, через который получает данные, и вы хотите где-то эти данные хранить, то Core Data — отличный выбор.Какие проблемы могут возникнуть с этим? Первое и самое очевидное — объем данных будет настолько велик, что при попытке его сохранить наше приложение на некоторое время зависнет, что отразится на пользовательском опыте.
Обычного НОД здесь недостаточно, поскольку, несмотря ни на что, наш Core Data Stack, о котором упоминалось, здесь , работает синхронно, и каждый раз, когда мы получаем доступ к нашему NSManageObjectContext, нам придется ждать конца цикла.
Но здесь нам на помощь приходит приватный NSManageObjectContext, который работает в фоновом потоке.
Чтобы его вызвать, вам необходимо сначала связаться с нашим NSPersistentContainer. Инициализация будет выглядеть так:
lazy var persistentContainer: NSPersistentContainer = { let container = NSPersistentContainer(name: "Preset") container.loadPersistentStores { (persistent, error) in if let error = error { fatalError("Error: " + error.localizedDescription) } } container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy container.viewContext.shouldDeleteInaccessibleFaults = true container.viewContext.automaticallyMergesChangesFromParent = true return container }()
Политика слияния
Здесь вы указываете политику слияния для нашего NSManageObjectContext. Здесь мы явно указываем, как должны вести себя Core Data в случае конфликта данных.Параметры MergePolicy:
- NSRolbackMergePolicy — Если возникает конфликт, отменяет все изменения до его возникновения.
- NSOverwriteMergePolicy — сохранит новые значения независимо от данных
- NSMergeByPropertyStoreTrumpMergePolicy — Сохраняет измененные объекты свойство за свойством, в этом случае сохраненные данные будут иметь преимущественную силу.
- NSMergeByPropertyObjectTrumpMergePolicy — Сохраняет измененные объекты свойство за свойством, в этом случае новые данные будут иметь преимущественную силу.
let context = persistentContainer.viewContext
let context = persistentContainer.newBackgroundContext()
Теперь у нас есть два NSManageObjectContext. Первый используется для работы с пользовательским интерфейсом и выполняется в основном потоке, а второй имеет PrivateQueueConcurrencyType для работы в фоновом режиме.
Мы будем использовать его для загрузки данных.
let object = NSEntityDescription.insertNewObject(forEntityName: "Name", into: context)
saveChanges(with: context)
Здесь мы создаём нашу Entity и далее можем присвоить ей необходимые свойства, после чего вызываем метод save, выглядит это так: func saveChanges(with context: NSManagedObjectContext) {
context.performAndWait {
if context.hasChanges {
do {
try context.save()
} catch {
context.rollback()
}
}
context.reset()
}
}
На выбор есть 2 метода:
- PerformAndWait — синхронно выполняет действия в потоке контекста.
- выполнить — выполняет действия в потоке контекста асинхронно.
Нсфетчедресултсконтроллер
NSFetchedResultsController — контроллер, выполняющий определенные запросы и показывающий пользователю необходимые данные.
lazy var fetchedResultsController: NSFetchedResultsController<Pack> = {
let fetchRequest = NSFetchRequest<Pack>(entityName:"Pack")
fetchRequest.fetchBatchSize = 20
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending:true)]
let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
controller.delegate = self
do {
try controller.performFetch()
} catch {
print(error.localizedDescription)
}
return controller
}()
NSFetchedResultsController имеет очень большое количество конфигураций, давайте рассмотрим парочку из них: ФетчЛимит FetchLimit — указывает ограничение на выборку объектов.
FetchOffset FetchOffset — указывает смещение.
Если вы укажете значение 2, то будут показаны элементы со второго элемента.
FetchBatchSize FetchBatchSize — указывает, сколько элементов будет загружено одновременно.
Если вы отображаете элементы в Table/CollectionView и одновременно отображается только 5 элементов, из соображений производительности лучше загружать не более 7 элементов одновременно, чем брать все данные одновременно и хранить их в памяти.
FetchBatchSize FetchBatchSize — устанавливает ограничение на объём, который весит объект и не будет его загружать, если объект превысит этот предел.
СортДескриптор SortDescriptor — указывает, по какому ключу следует сортировать запрос, а также по возрастанию или наоборот. ВозвращаетОбъектыАсFaults ReturnsObjectsAsFaults — указывает на то, что наши значения могут прийти пустыми, и когда мы получим к ним доступ, они будут загружены из нашего PersistentStore, которые в данный момент там находятся в виде RawCache На данный момент у нас есть NSFetchedResultsController, который должен отображать наши данные в таблице.
Чтобы обновить данные, вам нужно вызвать метод делегата: extension ViewController: NSFetchedResultsControllerDelegate {
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
collectionView.reloadData()
}
}
Этот метод делегата срабатывает, когда в нашем контексте происходят некоторые изменения.
В этой реализации это происходит после того, как мы сохраним данные в приватном контексте.
В этот момент срабатывает наш метод делегата и данные обновляются.
Всего пара шагов и Core Data превращается из обычной базы данных в мощное оружие для любого iOS-разработчика.
Приятного кодирования! Теги: #Apple #Swift #xcode #core data #objcetive-c #objc-c
-
Как Я Реализовал Функции Яндекс.музыки
19 Oct, 24 -
Профессиональное Управление Изменениями
19 Oct, 24