iOS 8: kjernedata og Asynchronous Henter
32
Del
7
Del
Dette Cyber Monday Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av
Dette innlegget er en del av en serie kalt kjernedata fra Scratch.iOS. 8: Kjerne Data- og Batch oppdateringer
I forrige artikkel om iOS 8 og Core data, diskuterte vi batch oppdateringer. Batch oppdateringer er ikke den eneste nye API i byen. Per iOS 8 og OS X Yosemite, er det mulig å asynkront hente data. I denne opplæringen, vil vi ta en nærmere titt på hvordan å implementere asynkron henting og i hvilke situasjoner søknaden din kan dra nytte av denne nye API.
1. Problemet
Som batch oppdateringer, har asynkron henting vært på ønskelisten til mange utviklere for en stund. Hente forespørsler kan være komplisert, tar en ikke ubetydelig mengde tid til å fullføre. I løpet av den tiden for hente forespørsel blokker tråden den kjører på, og som et resultat blokkerer tilgang til den administrerte forbindelse objektet utføre forespørselen hente. Problemet er enkle å forstå, men hva betyr Apples løsning se ut.
2. Løsningen
Apples svar på dette problemet er asynkron henting. En asynkron hente forespørsel kjører i bakgrunnen. Dette betyr at den ikke hindrer andre oppgaver mens det blir utført, for eksempel oppdatering av brukergrensesnittet på hovedtråden.
Asynkron henting idrett også to andre praktiske funksjoner, framdriftsrapportering og avbestillings. En asynkron hente forespørsel kan avbrytes når som helst, for eksempel når brukeren bestemmer seg for hente forespørsel tar for lang tid å fullføre. Progress rapportering er et nyttig tillegg til vise brukeren den nåværende tilstanden i hente forespørsel.
Asynkron henting er en fleksibel API. Ikke bare er det mulig å avbryte en asynkron hente forespørsel, er det også mulig å gjøre endringer i administrerte objektet sammenheng mens asynkron hente forespørsel blir henrettet. Med andre ord, kan brukeren fortsette å bruke programmet mens programmet utfører en asynkron hente forespørsel i bakgrunnen.
3. Hvordan virker det?
Som batch oppdateringer, asynkron hente forespørsler er overlevert til den administrerte objektet sammenheng som en NSPersistentStoreRequest objekt, en forekomst av NSAsynchronousFetchRequest klassen for å være presis.
En NSAsynchronousFetchRequest eksempel er initialisert med en NSFetchRequest objekt og en ferdigstillelse blokk. Gjennomføringen blokken blir utført når asynkron hente forespørsel har fullført sin hente forespørsel.
La oss se på to-do søknaden vi opprettet tidligere i denne serien, og erstatte dagens implementering av NSFetchedResultsController klasse med en asynkron hente forespørsel
Trinn 1:. Prosjektoppsett
Last ned eller klone prosjektet fra GitHub og åpne den i Xcode 6. Før vi kan begynne å jobbe med NSAsynchronousFetchRequest klasse, må vi gjøre noen endringer . Vi vil ikke være i stand til å bruke NSFetchedResultsController klasse for håndtering tabellen vise data siden NSFetchedResultsController klassen er designet for å kjøre på hovedtråden
Trinn 2:. Skifte Hentet de resultater Controller Anmeldelser
Start ved å oppdatere den private klasse forlengelse av TSPViewController klassen som vist nedenfor. Vi fjerner fetchedResultsController eiendom og opprette en ny eiendom, elementer av type NSArray for lagring av gjøremål. Dette betyr også at TSPViewController klassen ikke lenger trenger å samsvare med NSFetchedResultsControllerDelegate protokollen
interface TSPViewController ()property (sterk, nonatomic) NSArray * elementer;.property (Sterk, nonatomic) NSIndexPath * valg;end < p> Før vi refactor den viewDidLoad metoden, jeg først vil oppdatere gjennomføringen av UITableViewDataSource protokollen. Ta en titt på de endringene jeg har gjort i følgende kode blokker Anmeldelser - (NSInteger) numberOfSectionsInTableView:. (UITableView *) Tableview {return self.items? 1: 0;} - (NSInteger) Tableview: (UITableView *) Tableview numberOfRowsInSection: (NSInteger) seksjon {return self.items? self.items.count: 0;} - (void) configureCell: (TSPToDoCell *) celle atIndexPath: (NSIndexPath *) indexPath {//Fetch Record NSManagedObject * rekord = [self.items objectAtIndex: indexPath.row]; //Update Cell [cell.nameLabel setText: [rekord valueForKey: @ "navn"]]; [cell.doneButton setSelected: [[rekord valueForKey: @ "ferdig"] boolValue]]; [celle setDidTapButtonBlock: ^ {BOOL isdone = [[rekord valueForKey: @ "ferdig"] boolValue]; //Update Record [rekord SetValue: @ Forkey (isdone!): @ "Ferdig"]; }];} - (Void) Tableview: (UITableView *) Tableview commitEditingStyle: (UITableViewCellEditingStyle) editingStyle forRowAtIndexPath: (NSIndexPath *) indexPath {if (editingStyle == UITableViewCellEditingStyleDelete) {NSManagedObject * rekord = [self.items objectAtIndex: indexPath.row ]; if (rekord) {[self.managedObjectContext deleteObject: record]; .}}}
Vi må også endre en linje med kode i prepareForSegue: avsender: metode som vist nedenfor
//Fetch RecordNSManagedObject * rekord = [self.items objectAtIndex: self.selection.row]; < p> Sist men ikke minst, må du slette gjennomføringen av NSFetchedResultsControllerDelegate protokollen siden vi ikke lenger trenger det
Trinn 3:. Opprette Asynchronous Fetch Request
Som du kan se nedenfor, skaper vi asynkron hente forespørsel i visningen kontrollerens viewDidLoad metode. La oss ta et øyeblikk for å se hva som skjer Anmeldelser - (void) viewDidLoad {[super viewDidLoad].; //Hjelpere __weak TSPViewController * weakSelf = selv; //Initial Fetch Request NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] initWithEntityName: @ "TSPItem"]; //Legg Sorter Descriptors [fetchRequest setSortDescriptors: @ [[NSSortDescriptor sortDescriptorWithKey: @ "createdAt" stigende: YES]]]; //Initial asynkron Fetch Request NSAsynchronousFetchRequest * asynchronousFetchRequest = [[NSAsynchronousFetchRequest alloc] initWithFetchRequest: fetchRequest completionBlock: ^ (NSAsynchronousFetchResult * resultat) {dispatch_async (dispatch_get_main_queue () ^ {//Process Asynchronous Fetch Resultat [weakSelf processAsynchronousFetchResult: Resultatet];}); }]; //Execute Asynchronous Fetch Request [self.managedObjectContext performBlock: ^ {//Execute Asynchronous Fetch Request NSError * asynchronousFetchRequestError = null; NSAsynchronousFetchResult * asynchronousFetchResult = (NSAsynchronousFetchResult *) [weakSelf.managedObjectContext executeRequest: asynchronousFetchRequest error: & asynchronousFetchRequestError]; if (asynchronousFetchRequestError) {NSLog (@ "Kan ikke kjøre asynkron hente resultatet."); NSLog (@ "% @,% @", asynchronousFetchRequestError, asynchronousFetchRequestError.localizedDescription); }}];}
Vi starter med å opprette og konfigurere en NSFetchRequest eksempel for å initialisere asynkron hente forespørsel. Det er dette hente anmodning om at den asynkrone hente forespørsel vil kjøre i bakgrunnen
//Initial Fetch RequestNSFetchRequest * fetchRequest = [[NSFetchRequest alloc] initWithEntityName: @ "TSPItem"]; //Legg Sorter Descriptors [fetchRequest setSortDescriptors:. @ [ ,,,0],[NSSortDescriptor sortDescriptorWithKey: @ "createdAt" stigende: YES]]];
For å initialisere en NSAsynchronousFetchRequest eksempel påberope vi initWithFetchRequest: completionBlock :, passerer fetchRequest og en ferdigstillelse blokk
//Initial asynkron Fetch RequestNSAsynchronousFetchRequest * asynchronousFetchRequest. = [[NSAsynchronousFetchRequest alloc] initWithFetchRequest: fetchRequest completionBlock: ^ (NSAsynchronousFetchResult * resultat) {dispatch_async (dispatch_get_main_queue () ^ {//Process Asynchronous Fetch Resultat [weakSelf processAsynchronousFetchResult: Resultatet];});}];
ferdigstillelse blokk startes når den asynkrone hente forespørsel har avsluttet gjennomføringen av selskapets hente forespørsel. Gjennomføringen blokk tar ett argument av typen NSAsynchronousFetchResult, som inneholder resultatet av spørringen samt en referanse til den opprinnelige asynkron hente forespørsel.
I gjennomføringen blokken, påberope vi processAsynchronousFetchResult :, bestått i NSAsynchronousFetchResult objekt . Vi vil ta en titt på denne hjelperen metoden i en liten stund.
Gjennomføring av asynkron hente forespørsel er nesten identisk med hvordan vi gjennomføre en NSBatchUpdateRequest. . Vi kaller executeRequest: error: på den administrerte objektet sammenheng, passerer i asynkron hente forespørsel og en peker til et NSError objekt
[self.managedObjectContext performBlock: ^ {//Execute Asynchronous Fetch Request NSError * asynchronousFetchRequestError = null; NSAsynchronousFetchResult * asynchronousFetchResult = (NSAsynchronousFetchResult *) [weakSelf.managedObjectContext executeRequest: asynchronousFetchRequest error: & asynchronousFetchRequestError]; if (asynchronousFetchRequestError) {NSLog (@ "Kan ikke kjøre asynkron hente resultatet."); NSLog (@ "% @,% @", asynchronousFetchRequestError, asynchronousFetchRequestError.localizedDescription); }}];
Merk at vi utføre asynkrone hente forespørsel ved å ringe performBlock: på greid objektet sammenheng. Selv om dette er strengt tatt ikke nødvendig siden den viewDidLoad metode, der vi skaper og utføre asynkron hente forespørsel, kalles på hovedtråden, er det en god vane og beste praksis for å gjøre det.
Selv om den asynkrone hente forespørsel kjøres i bakgrunnen, merk at executeRequest: error: metoden returnerer umiddelbart, levere oss en NSAsynchronousFetchResult objekt. Når asynkron hente forespørsel fullfører, at samme NSAsynchronousFetchResult objektet er befolket med resultatet av hente forespørsel.
Til slutt sjekker vi om den asynkrone hente forespørselen ble utført uten problemer ved å sjekke om den NSError objektet er lik null .
Trinn 4: Behandling av Asynchronous Fetch Resultat
processAsynchronousFetchResult: Metoden er ikke noe mer enn en hjelper metode der vi behandler et resultat av den asynkrone hente forespørsel. Vi setter visningen kontrollerens elementer eiendom med innholdet i resultatets finalResult eiendom og laste tabellvisningen Anmeldelser - (void) processAsynchronousFetchResult:. (NSAsynchronousFetchResult *) asynchronousFetchResult {if (asynchronousFetchResult.finalResult) {//Oppdater Objekt [selvtillit setItems : asynchronousFetchResult.finalResult]; //Reload Tabell [self.tableView reloadData]; }}
Trinn 5: Bygg og Kjør
Bygg prosjektet og kjøre programmet på iOS Simulator. Du kan bli overrasket over å se programmet krasjer når den prøver å utføre asynkron hente forespørsel. Heldigvis forteller produksjonen i konsollen oss hva som gikk galt
*** Avslutte app grunn uoppfanget unntak 'NSInvalidArgumentException', grunn:. 'NSConfinementConcurrencyType sammenheng < NSManagedObjectContext: 0x7fce3a731e60 > kan ikke støtte asynkron hente forespørsel < NSAsynchronousFetchRequest: 0x7fce3a414300 > med hente forespørsel < NSFetchRequest: 0x7fce3a460860 > (enhet: TSPItem; predikat: ((null)); sortDescriptors: (("(createdAt, stigende, sammenligne :)")); Type:. NSManagedObjectResultType;) '
Hvis du ikke har lest artikkelen om kjerne data og samtidighet, kan du bli forvirret av hva du leser. Husk at kjernedata erklærer tre samtidighet typer, NSConfinementConcurrencyType, NSPrivateQueueConcurrencyType, og NSMainQueueConcurrencyType. Når du oppretter en administrert objekt sammenheng ved å påberope klassens init-metoden, er den resulterende klarte objektet sammenheng er samtidighet typen lik NSConfinementConcurrencyType. Dette er standardsamtidighetstype.
Problemet er imidlertid at asynkron henting er uforenlig med NSConfinementConcurrencyType type. Uten å gå i for mye detalj, er det viktig å vite at den asynkrone hente forespørsel trenger å slå sammen resultatene av sin hente forespørsel med den administrerte objektet kontekst som utførte den asynkrone hente forespørsel. Den trenger å vite på hvilken utsendelse køen den kan gjøre dette, og det er derfor kun NSPrivateQueueConcurrencyType og NSMainQueueConcurrencyType støtte asynkron henting. Løsningen er veldig enkel skjønt
Trinn 6:.. Konfigurering av Managed Object Context
Åpne TSPAppDelegate.m Hotell og oppdatere managedObjectContext metoden som vist nedenfor Anmeldelser - (NSManagedObjectContext *) managedObjectContext {if (_managedObjectContext) {return _managedObjectContext; } NSPersistentStoreCoordinator * koordinator = [selvtillit persistentStoreCoordinator]; if (koordinator) {_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSMainQueueConcurrencyType]; [_managedObjectContext setPersistentStoreCoordinator: koordinator]; } Returnere _managedObjectContext;}
Den eneste endringen vi har gjort er å bytte ut init-metoden med initWithConcurrencyType :, passerer NSMainQueueConcurrencyType som argument. Dette betyr at den klarte objektet sammenheng bør bare nås fra hovedtråden. Dette fungerer greit så lenge vi bruker performBlock: eller performBlockAndWait:. Metoder for å få tilgang til administrerte objektet sammenheng
Kjør prosjektet en gang til for å forsikre deg om at vår endringen har faktisk løst problemet
<. h2> 4. Viser Progress
NSAsynchronousFetchRequest klassen legger til støtte for å overvåke fremdriften av hente forespørsel, og det er også mulig å avbryte en asynkron hente forespørsel, for eksempel hvis brukeren bestemmer seg for at det tar for lang tid å fullføre. Anmeldelser
Den NSAsynchronousFetchRequest klasse utnytter NSProgress klassen for framdriftsrapportering samt avlyser en asynkron hente forespørsel. Den NSProgress klasse, tilgjengelig siden iOS 7 og OS X 10.9, er en smart måte å overvåke fremdriften for en oppgave uten å måtte tett par oppgaven til brukergrensesnittet.
NSProgress klassen støtter også kanselering, som er hvordan en asynkron hente forespørsel kan bli kansellert. La oss finne ut hva vi må gjøre for å implementere framdriftsrapportering for asynkron hente forespørsel
Trinn 1:. Legge SVProgressHUD
Vi vil vise brukeren fremdriften av asynkron hente forespørselen ved hjelp Sam Vermette sin SVProgressHUD bibliotek. Last ned biblioteket fra GitHub og legg til SVProgressHUD
mappe til Xcode prosjekt
Trinn 2:. Sette opp NSProgress
I denne artikkelen vil vi ikke utforske NSProgress klasse i mye detalj, men gjerne lese mer om det i dokumentasjonen. Vi skaper en NSProgress eksempel i blokken vi hånd til performBlock: metode i visningen kontrollerens viewDidLoad metode
//Opprett ProgressNSProgress * fremgang = [NSProgress progressWithTotalUnitCount: 1];. //Bli Nåværende [fremgang becomeCurrentWithPendingUnitCount: 1];
Du kan bli overrasket over at vi setter den totale enhet telle til 1. Grunnen er enkel. Når kjernedata utfører asynkron hente forespørsel, betyr det ikke vet hvor mange poster det vil finne i den vedvarende butikken. Dette betyr også at vi ikke vil være i stand til å vise den relative fremgang til bruker en prosentandel. I stedet vil vi vise brukeren den absolutt fremgang-antall poster den har funnet.
Du kan bøte på dette problemet ved å utføre en hente forespørsel å hente antall poster før du utfører asynkron hente forespørsel. Jeg foretrekker å ikke gjøre dette, men fordi dette betyr også at henting av poster fra den vedvarende butikken tar lengre tid å fullføre på grunn av den ekstra hente forespørsel i starten
Trinn 3:. Legge til en Observer Anmeldelser
Når vi utføre asynkron hente forespørsel, er vi umiddelbart overlevert et NSAsynchronousFetchResult objekt. Dette objektet har en fremgang eiendom, som er av typen NSProgress. Det er denne fremgangen eiendom som vi trenger for å observere hvis vi ønsker å motta oppdateringer fremgang
//Execute Asynchronous Fetch Request [self.managedObjectContext performBlock: ^ {//Opprett Progress NSProgress * fremgang = [NSProgress progressWithTotalUnitCount. 1]; //Bli Nåværende [fremgang becomeCurrentWithPendingUnitCount: 1]; //Execute Asynchronous Fetch Request NSError * asynchronousFetchRequestError = null; NSAsynchronousFetchResult * asynchronousFetchResult = (NSAsynchronousFetchResult *) [self.managedObjectContext executeRequest: asynchronousFetchRequest error: & asynchronousFetchRequestError]; if (asynchronousFetchRequestError) {NSLog (@ "Kan ikke kjøre asynkron hente resultatet."); NSLog (@ "% @,% @", asynchronousFetchRequestError, asynchronousFetchRequestError.localizedDescription); } //Legg Observer [asynchronousFetchResult.progress addObserver bolig: forKeyPath: @ "completedUnitCount" alternativer: NSKeyValueObservingOptionNew kontekst: ProgressContext]; //Melde Nåværende [fremgang resignCurrent];}];
Legg merke til at vi kaller resignCurrent om fremdriften objekt å balansere tidligere becomeCurrentWithPendingUnitCount: ring. Husk at begge disse metodene må startes på samme tråd
Trinn 4:. Fjerne Observer
I gjennomføringen blokk av den asynkrone hente forespørsel, fjerner vi observatøren og avfeie fremdriften HUD
//Initial asynkron Fetch RequestNSAsynchronousFetchRequest * asynchronousFetchRequest = [[NSAsynchronousFetchRequest alloc] initWithFetchRequest. fetchRequest completionBlock: ^ (NSAsynchronousFetchResult * resultat) {dispatch_async (dispatch_get_main_queue () ^ {//Avvis Progress HUD [SVProgressHUD avvise ]; //Process Asynchronous Fetch Resultat [weakSelf processAsynchronousFetchResult: Resultatet]; //Fjern Observer [result.progress removeObserver: weakSelf forKeyPath: @ "completedUnitCount" kontekst: ProgressContext];});}];
Før vi implementere observeValueForKeyPath : ofObject: endring: kontekst :, vi må legge til en import regnskapet for SVProgressHUD bibliotek, erklærer den statiske variable ProgressContext at vi passerer i så sammenheng da legge til og fjerne observatøren, og viser fremdriften HUD før du oppretter asynkron hente forespørsel .
#import "SVProgressHUD /SVProgressHUD.h" static void * ProgressContext = & ProgressContext, - (void) viewDidLoad {[super viewDidLoad]; //Hjelpere __weak TSPViewController * weakSelf = selv; //Show Progress HUD [SVProgressHUD showWithStatus: @ "Henter data" maskType: SVProgressHUDMaskTypeGradient]; //Initial Fetch Request NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] initWithEntityName: @ "TSPItem"]; //Legg Sorter Descriptors [fetchRequest setSortDescriptors: @ [[NSSortDescriptor sortDescriptorWithKey: @ "createdAt" stigende: YES]]]; //Initial asynkron Fetch Request NSAsynchronousFetchRequest * asynchronousFetchRequest = [[NSAsynchronousFetchRequest alloc] initWithFetchRequest: fetchRequest completionBlock: ^ (NSAsynchronousFetchResult * resultat) {dispatch_async (dispatch_get_main_queue () ^ {//avvise Fremskritts HUD [SVProgressHUD avfeie]; //Process Asynchronous Fetch Resultatet [weakSelf processAsynchronousFetchResult: Resultatet]; //Fjern Observer [result.progress removeObserver: weakSelf forKeyPath: @ "completedUnitCount" kontekst: ProgressContext];}); }]; //Execute Asynchronous Fetch Request [self.managedObjectContext performBlock: ^ {//Opprett Progress NSProgress * fremgang = [NSProgress progressWithTotalUnitCount: 1]; //Bli Nåværende [fremgang becomeCurrentWithPendingUnitCount: 1]; //Execute Asynchronous Fetch Request NSError * asynchronousFetchRequestError = null; NSAsynchronousFetchResult * asynchronousFetchResult = (NSAsynchronousFetchResult *) [weakSelf.managedObjectContext executeRequest: asynchronousFetchRequest error: & asynchronousFetchRequestError]; if (asynchronousFetchRequestError) {NSLog (@ "Kan ikke kjøre asynkron hente resultatet."); NSLog (@ "% @,% @", asynchronousFetchRequestError, asynchronousFetchRequestError.localizedDescription); } //Legg Observer [asynchronousFetchResult.progress addObserver bolig: forKeyPath: @ "completedUnitCount" alternativer: NSKeyValueObservingOptionNew kontekst: ProgressContext]; //Melde Nåværende [fremgang resignCurrent]; }];}
Trinn 5: Fremskritts Rapportering
Alt som gjenstår for oss å gjøre, er å gjennomføre observeValueForKeyPath: ofObject: endring: kontekst: metode. Vi sjekker om sammenhengen er lik ProgressContext, skape en status objekt ved å trekke antall fullførte poster fra endringen ordboken, og oppdatere fremdriften HUD. Merk at vi oppdaterer brukergrensesnittet på hovedtråden Anmeldelser - (void) observeValueForKeyPath:. (NSString *) nøkkelbane ofObject: (id) objekt endring: (NSDictionary *) endring sammenheng: (void *) sammenheng {if (kontekst == ProgressContext) {dispatch_async (dispatch_get_main_queue () ^ {//Opprett Status NSString * status = [NSString stringWithFormat: @ "Hentet% li Records", (lang) [[endre objectForKey: @ "nye"] integerValue]]; //Show Progress HUD [SVProgressHUD setStatus: status];}); }}
5. Dummy data
Hvis vi ønsker å teste vår søknad på riktig måte, trenger vi mer data. Selv om jeg ikke anbefale å bruke følgende tilnærming i en produksjon program, er det en rask og enkel måte å fylle databasen med data
Åpne TSPAppDelegate.m Kjøpe og oppdatere programmet. DidFinishLaunchingWithOptions : Fremgangsmåten som er vist nedenfor. Den populateDatabase metoden er en enkel helper metode der vi legger dummy data til databasen Anmeldelser - (BOOL) program: (UIApplication *) søknad didFinishLaunchingWithOptions:. (NSDictionary *) launchOptions {//Befolke Database [selvtillit populateDatabase]; ... Tilbake JA;}
Gjennomføringen er grei. Fordi vi bare ønsker å sette inn dummy data en gang, sjekker vi det brukerstandarder database for nøkkelen @ "didPopulateDatabase". Hvis nøkkelen ikke er satt, setter vi dummy data Anmeldelser - (void) populateDatabase {//Hjelpere NSUserDefaults * ud = [NSUserDefaults standardUserDefaults].; if ([ud objectForKey: @ "didPopulateDatabase"]) tilbake; for (NSInteger i = 0; i < 1.000.000; i ++) {//Lag Entity NSEntityDescription * enhet = [NSEntityDescription entityForName: @ "TSPItem" inManagedObjectContext: self.managedObjectContext]; //Initial Record NSManagedObject * record = [[NSManagedObject alloc] initWithEntity: enhet insertIntoManagedObjectContext: self.managedObjectContext]; //Befolke Record [rekord SetValue: [NSString stringWithFormat: @ "Sak% li", (lang) i] Forkey: @ "navn"]; [rekord SetValue: [NSDate dato] Forkey: @ "createdAt"]; } //Lagre Managed Object Kontekst [selvtillit saveManagedObjectContext]; //Oppdater Brukerinnstillinger [ud setBool: JA Forkey: @ "didPopulateDatabase"];}
Antall poster er viktig. Hvis du planlegger å kjøre programmet på iOS Simulator, så det er greit å sette inn 100.000 eller 1.000.000 poster. Dette vil ikke fungere like bra på en fysisk enhet, og vil ta for lang tid å fullføre.
I for loop, skaper vi en administrert objekt og fylle den med data. Merk at vi ikke lagre endringene av den administrerte objekt sammenheng i løpet av hver iterasjon av for loop.
Til slutt, vi oppdaterer den brukerstandarder database for å sørge for at databasen fylles ikke neste gang programmet er lansert.
Great. Kjør programmet i iOS Simulator for å se resultatet. Du vil merke at det tar en liten stund for asynkron hente forespørsel om å begynne å hente poster og oppdatere fremdriften HUD.
6. Breaking Endringer
Ved å erstatte hentet resultater kontrolleren klasse med en asynkron hente forespørsel, har vi brutt et par stykker av programmet. For eksempel ikke peke på haken av en to-do elementet ikke ut til å fungere lenger. Mens databasen blir oppdatert, ikke brukergrensesnittet ikke nødvendigvis den endringen. Løsningen er ganske enkelt å fikse, og jeg skal la det opp til deg å implementere en løsning. Du skal nå ha nok kunnskap til å forstå problemet og finne en passende løsning.
Konklusjon
Jeg er sikker på at du enig i at asynkron henting er overraskende lett å bruke. Den tunge løft er gjort av kjernedata, noe som betyr at det ikke er behov for å manuelt slå sammen resultatene av den asynkrone hente forespørselen med klarte objektet sammenheng. Din eneste jobb er å oppdatere brukergrensesnittet når asynkron hente forespørsel hender du sine resultater. Sammen med batch oppdateringer, det er et flott tillegg til Core data rammeverket.
Denne artikkelen konkluderer også denne serien på kjernedata. Du har lært mye om kjernedata rammeverket og du vet alle de essensielle for å bruke Core data i en reell søknad. Kjernen Data er et kraftig rammeverk, og med utgivelsen av iOS 8, har Apple vist oss at det blir bedre for hvert år.