Hva er en kjernedatafeil?

What Er en Core datafeil?
21
Del
8
Del
Dette Cyber Mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.

Feil er en viktig del av kjernedata. Selv om begrepet høres illevarslende, feil er iboende i livssyklusen til en Core data posten. I denne opplæringen vil du lære hva feil er, hvordan man skal håndtere dem, og hvordan du kan feilsøke problemer knyttet til forkastninger.

Forutsetninger

Kjerne data er et avansert tema så jeg 'm kommer til å anta at du allerede er kjent med Xcode og iOS utvikling. Selv om jeg skal bruke den Swift programmeringsspråk for denne opplæringen, er alt i denne opplæringen også gjeldende for Objective-C.

Wat er en feil?

Kjerne data er veldig flinke til hva det gjør takket være hardt arbeid av Apples kjernedata team. Kjernen Data svært optimalisert for å holde minnet fotavtrykk lavt uten å ofre ytelse. Forkastninger er en av teknikkene kjernedata bruker for å forbruke så lite minne som mulig.

Feilende er ikke unikt for kjernedata. En lignende teknikk brukes i mange andre rammer, slik som aske og Ruby på skinner. Ideen er enkel, bare laste data når det er nødvendig. For å gjøre forkastninger arbeid, gjør kjernedata litt magi under panseret ved å opprette egendefinerte underklasser på kompilering som representerer feil. La oss se hvordan dette fungerer med et eksempel.

Jeg har laget en enkel prøve programmet til å jobbe med. Last ned Xcode prosjekt fra GitHub og åpne den i Xcode. Prosjektet bruker Swift 2.1, noe som betyr at du trenger Xcode 7.1 eller nyere for å tilfredsstille kompilatoren.

Datamodellen inneholder to enheter, List og Element. En liste kan ha null eller flere elementer, og et element er alltid knyttet til en liste. Det er et klassisk eksempel på en en-til-mange-relasjon.

Kjør programmet og fylle den vedvarende butikken, en SQLite database, med noen data ved å opprette noen lister og elementer. Avslutt applikasjonen når du er ferdig.

Firing Feil

Du skal nå ha et program med noen data. La oss se hvordan feil fungere i praksis ved å legge noen utskrifts uttalelser. Åpne ListsViewController.swift og søke etter prepareForSegue (_: avsender :). I denne metoden, vi hente en liste brukeren har valgt i visningen tabellen. Uncomment utskrifts uttalelser i prepareForSegue (_:. Avsender :) som vist i gjennomføringen nedenfor
styre func prepareForSegue (naturlig overgang: UIStoryboardSegue, avsender:? AnyObject) {if segue.identifier == SegueListViewController {vakt la indexPath = Tableview. indexPathForSelectedRow else {retur} //Fetch List la list = self.fetchedResultsController.objectAtIndexPath (indexPath) som! List print ("1: \\ (liste)") hvis la varer = list.items {print ("2: \\ (eks)") print ("3: \\ (items.count)") print ("4: \\ (eks) ") hvis la element = items.anyObject () {print (" 5: \\ (post) ") print (" 6: \\ (item.name) ") print (" 7: \\ (post) ") }} print ("8: \\ (liste)") //Fetch Destinasjon View Controller la listViewController = segue.destinationViewController som! ListViewController //Konfigurer View Controller listViewController.list = liste}}

Kjør programmet og klikk på én av listene i listene vise kontrolleren. Eksempelet er bare interessant hvis du klikker på en liste som har ett eller flere elementer knyttet til den. La oss inspisere utgangen av utskrifts uttalelser trinnvis
1: < Faulting.List. 0x154e5d0b0 > (enhet: List; id: 0xd0000000001c0000 < x-coredata: //804E0602-42B4-4EB5-A1D0-653848363595 /List /p7 >, data: {elementer = "< forholdet feil: 0x154e3d5b0 objekter '>"; name = "List 6";})

Den første tingen å merke seg er klassenavnet, Faulting.List. Dette er hva vi kan forvente siden modulen er oppkalt Feilende og klassen er oppkalt List. I Swift, er hele klassen navnet på en klasse består av modulen navn og klasse navn.

Utgangen i konsollen viser også navnet på foretaket, List, og en ordbok av data. Navnet attributtet er satt til liste 6 mens elementene attributt er markert som et forhold feil. Dette er den første typen feil i grunndata. Kjerne data forstår at det er ikke nødvendig å laste forholdet. I stedet, markerer det forholdet som en feil. Den andre print uttalelse bekrefter dette som du kan se nedenfor
2: Forholdet 'elementer' feil på greid objekt (0x154e5d0b0) < Faulting.List. 0x154e5d0b0 > (enhet: List; id: 0xd0000000001c0000 < x-coredata: //804E0602-42B4-4EB5-A1D0-653848363595 /List /p7 >, data: {elementer = "< forholdet feil: 0x154e3d5b0 objekter '>"; name = "List 6";})

Den tredje print uttalelse, derimot, er mer interessant. Den skriver ut antall elementer knyttet listen
3: 2.

Kjerne Data kan bare gjøre dette ved å skyte forholdet feil. Det spør den vedvarende butikken for de elementene som er tilknyttet listen. Dette er imidlertid bare en del av historien som illustrert ved den fjerde print uttalelse
4: Forholdet "elementer" på greid objekt (0x154e5d0b0) < Faulting.List. 0x154e5d0b0 > (enhet: List; id: 0xd0000000001c0000 < x-coredata: //804E0602-42B4-4EB5-A1D0-653848363595 /List /p7 >, data: {elementer = ("0xd000000000540002 < x-coredata: //804E0602-42B4 -4EB5-A1D0-653848363595 /post /p21 > "," 0xd000000000580002 < x-coredata: //804E0602-42B4-4EB5-A1D0-653848363595 /post /p22 > "); name =" List 6 ";}) med gjenstander {(< Faulting.Item: 0x154e83d60 > (enhet: Element; id: 0xd000000000540002 < x-coredata: //804E0602-42B4-4EB5-A1D0-653848363595 /post /p21 >, data: < feil >), < Faulting.Item: 0x154e55e50 > (enhet: Element; id: 0xd000000000580002 < x-coredata: //804E0602-42B4-4EB5-A1D0-653848363595 /post /p22 >, data: < feil >))}

Vi ser ikke lenger et forhold feil, men vi ser fortsatt en feil. Hva er det om? Kjernen Data kan bare gi oss hvor mange elementer for listen ved å skyte eller å løse forholdet feil. Men dette betyr ikke at kjernedata løser elementer av forholdet. Utgangen i konsollen bekrefter dette.

Vi kan se at postene for elementene er der, inkludert den som identifiserer kjernedata bruker internt. Dataene ordboken, derimot, er merket som en feil. Igjen, bare kjernedata gir oss det vi ber om. Heldigvis er nitty sandete detaljer håndteres av grunndata.

La oss grave litt dypere og hente en av elementer fra listen. Vi gjør dette ved å ringe anyObject () på elementene objekt. Vi trykker den resulterende elementet i den femte utskrifts uttalelse
5: < Faulting.Item. 0x144d7f100 > (enhet: Element; id: 0xd000000000540002 < x-coredata: //804E0602-42B4-4EB5-A1D0-653848363595 /post /p21 >, data: < feil >)

Utgangen bør ikke overraske deg. Utgangen bekrefter at vi har å gjøre med et element enhet. Ikke overraskende, er dataene ordboken fortsatt merket som en feil. I den sjette print uttalelse, vi skrive navnet egenskap av elementet
. 6: Element 0

Fordi vi be om verdien av et attributt av posten, branner kjernedata feilen å gi oss denne verdien. Den henter data for varen og fyller ut data ordbok. Den syvende print uttalelse bekrefter disse funnene
7: < Faulting.Item. 0x144d7f100 > (enhet: Element; id: 0xd000000000540002 < x-coredata: //804E0602-42B4-4EB5-A1D0-653848363595 /post /p21 >, data: {list = "0xd0000000001c0000 < x-coredata: //804E0602-42B4- 4EB5-A1D0-653848363595 /List /p7 > "; name =" Element 0 ";})

Data ordboken inneholder navnet attributtet samt listen forholdet. Den åttende og siste utskrifts uttalelse viser at forholdet feil av objektlisten er løst
8:. ≪ Faulting.List: 0x144e55da0 > (enhet: List; id: 0xd0000000001c0000 < x-coredata: //804E0602-42B4-4EB5-A1D0-653848363595 /List /p7 >, data: {elementer = ("0xd000000000540002 < x-coredata: //804E0602-42B4 -4EB5-A1D0-653848363595 /post /p21 > "," 0xd000000000580002 < x-coredata: //804E0602-42B4-4EB5-A1D0-653848363595 /post /p22 > "); name =" List 6 ";}) < h2> stand til å oppfylle en Fault

Jeg bestemte meg for å skrive denne artikkelen for å forklare et problem mange utviklere å bruke Core data kjøre inn på ett eller annet, å avfyre ​​en feil som ikke kan oppfylles. Problemet er enkel. La oss anta at du har en liste med en rekke elementer, og på et tidspunkt, slettes bruker listen. Hva skjer med elementer av denne listen? Hva skjer hvis kjernedata forsøker å fyre listen forholdet til en av de elementene som tilhørte den listen? La oss finne det ut.

La oss se prosjektet du har lastet ned fra GitHub. Åpne Faulting.xcdatamodeld, prosjektets datamodell. Velg elementer forholdet av listen enhet og åpne datamodellen Inspector til høyre. Hva er av interesse for oss er sletteregelen, som er satt til Cascade. Dette betyr at hvert element på listen blir slettet når listen er slettet. Dette er fornuftig, siden vi ikke ønsker å ha forlatt elementer som ikke er knyttet til en liste.

Velg listen forholdet mellom Element enhet og åpne datamodellen Inspector. Sletteregelen for dette forholdet er satt til opphever. Dette betyr at målet for forholdet, objektlisten, er satt til null når målet posten, posten, blir slettet. Dette er standard slette regelen for et forhold.

Kjør programmet, lage noen lister og elementer, og trykk på Elementer knappen øverst til venstre for å vise hvert element du har opprettet. Pek Avbryt i venstre, slette en av listene, og trykk på Elementer knappen igjen for å se hva som er endret. Som forventet, har de elementene som er tilknyttet den slettede liste også blitt slettet av kjernedata. Dette er ingen magisk. Kjernen data utfører bare de sletteregler vi definert i datamodellen.

Vi kan konkludere med at sammenhengene er satt opp riktig for denne type program. Men hva skjer hvis vi ikke konfigurerer slettereglene korrekt. Åpne datamodellen og sette sletteregelen for både relasjoner, elementer og listen, Ingen handling. Starte programmet på nytt og lage noen lister og elementer. Hvis du sletter en liste, og trykk på elementer-knappen øverst til venstre for å se hvert element i den vedvarende butikken, bør de elementene som er tilknyttet den slettede listen fortsatt være der. De var slettes ikke selv om listen som de tilhører har blitt fjernet.

Klikk på en av listene, og se hva som skjer. Hvis du kjører programmet på iOS 8, da søknaden vil krasje på grunn av en uoppfanget unntak. Hvis du kjører programmet på iOS 9, da vil du bare se en feil i konsollen. Stopp skrape hodet og la oss finne ut av dette sammen.

Objekt Utilgjengelige

Selv om programmet krasjer på iOS 8, er utgangs vi ser i konsollen tydelig og rett på sak.
Feilende [7189: 2427906] *** Avslutte app grunn uoppfanget unntak 'NSObjectInaccessibleException', grunn: 'CoreData ikke kunne oppfylle en feil for' 0x175b2ba0 < x-coredata: //3920E0C9-6613-47E6-AA19-66AF6555140A /List /p1 > ''

Det første du legger merke til er at programmet krasjet på grunn av en uoppfanget unntak. Hva er mer viktig for vår diskusjon, derimot, er årsaken til at unntaket ble kastet. Kjernen data forteller oss at det var ute av stand til å oppfylle en feil for et forhold. Forholdet kjernedata refererer til er listen forholdet av elementet vi tappet i tabellvisningen

Hvis du ser på gjennomføringen av Tableview (Tableview. DidSelectRowAtIndexPath :), så vil du forstå hvorfor kjernedata kastet et unntak. I denne metoden, vi hente varen brukeren tappet og skrive navnet på listen til konsollen
func Tableview. (Tableview: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {tableView.deselectRowAtIndexPath (indexPath, animert: true) hvis utleid element = self.fetchedResultsController.objectAtIndexPath (indexPath) som? Item {print (item.list? .name)}}

Fordi listen forholdet er en feil, må kjernedata for å fyre av feil å løse det. Dette betyr at grunndata ber vedvarende butikken for listen posten. Problemet er at posten er ikke lenger i den vedvarende butikken, og det er derfor et unntak ble kastet.

Slett Utilgjengelige Feil

Frem til iOS 9, har dette alltid vært standard virkemåte. Per iOS 9, Core data ikke lenger kaster et unntak. I stedet, logger det en kryptisk melding til konsollen. Til tross for meldingen er uklart, fortsatt inneholder det årsaken til problemet
Feilende [2 806: 1306995] CoreData: advarsel: En NSManagedObjectContext delegat overvurdere feil håndtering atferd å stille slette objektet med ID '0xd000000000140000 < x-coredata.: //396CF04E-B8B4-4108-8719-3C651F880C33 /List /p5 > ' og erstatning nil /0 for alle eiendomsverdier i stedet for å kaste.

Kjernen er at kjernedata ikke lenger kaster et unntak når det ikke er i stand til å oppfylle en feil. Den noe gode nyheten er at søknaden din ikke lenger krasjer hvis du ikke fanger unntaket.

Grunnen til ikke å kaste et unntak på iOS 9 skyldes innføringen av en ny eiendom, shouldDeleteInaccessibleFaults, og en ny metode, shouldHandleInaccessibleFault (_: forObjectID: triggeredByProperty :), på NSManagedObjectContext klasse. Jeg vil ikke dekke disse tilleggene i denne opplæringen.

Hva du trenger å huske er at iOS 9, som standard, setter shouldDeleteInaccessibleFaults til sann. Dette betyr at et utilgjengelig klarte objekt er merket som slettet og dens egenskaper er nullet ut. Hvis shouldDeleteInaccessibleFaults er satt til false, går grunndata til den gamle atferden ved å kaste et unntak

Selvfølgelig, shouldDeleteInaccessibleFaults eiendommen går hånd i hånd med shouldHandleInaccessibleFault (_:. ForObjectID: triggeredByProperty :). Hvis du overstyre denne metoden, kan du håndtere utilgjengelige objekter mer elegant.

Håndtering Feil

Når du møter et unntak på grunn av kjernedata ikke er i stand til å oppfylle en feil, kan du tenke kjernedata er å være litt aggressiv. Denne reaksjonen er ganske vanlig for folk nye til rammeverket. Sannheten er at utbygger er feil. Kjernen Data ble utformet med et bestemt sett av mål i tankene og forkastninger er en viktig komponent for å realisere disse målene.

Til tross for navnet, feil skal alltid være fulfillable. Dersom en feil ikke kan oppfylles, så det betyr at datamodellen er ikke satt opp riktig, eller programmet er ikke respekterer reglene fastsatt av grunndata rammeverket.

I kjernedata Programming Guide, Apple lister opp en rekke scenarier som kan føre til feil som ikke lenger kan oppfylles. De mest vanlige scenarier er feilkonfigurert relasjoner (slette regler) og sletting av en administrert objekt mens programmet fortsatt har en sterk referanse til som klarte objekt.

Vær advart, det er andre mulige scenarier. Fra min erfaring, utviklere ofte støte på lignende problemer på grunn av et problem med kjernedata stabelen. For eksempel, hvis programmet holder en sterk referanse til en administrert objekt, og på et tidspunkt, deallokerer forvaltet objekt sammenheng som klarte objekt, da kjernedata er ikke lenger i stand til å oppfylle noen feil for som klarte objekt. Jeg håper du forstår at dette ikke skal skje hvis du spiller av grunndata regler.

Konklusjon

Kjernedatafeil er utrolig nyttig og en viktig del av Apples utholdenhet rammeverk. Jeg håper denne artikkelen har lært deg hvordan man skal håndtere feil og hvor du skal lete etter hvis du får feil som ikke kan oppfylles. Hvis du har spørsmål, kan du gjerne la dem i kommentarfeltet nedenfor eller nå ut til meg på Twitter.



Previous:
Next Page: