2013-01-13 21 views
9

utworzyć obiekt i zapisać go kategorii:Nie można zaktualizować obiekt, który nigdy nie został wstawiony

NSManagedObjectContext *managedObjectContext = [[FTAppDelegate sharedAppDelegate] managedObjectContext]; 

    _category = (Category *)[NSEntityDescription 
          insertNewObjectForEntityForName:@"Category" 
          inManagedObjectContext:managedObjectContext]; 

    NSError *error = nil; 
    [managedObjectContext save:&error]; 
    if (error) { 
     NSLog(@"error saving: %@",error); 
    } 

następnie zmienić nazwę obiektu kategorii i zapisać ponownie.

_category.name = _nameTextField.text; 

    NSManagedObjectContext *managedObjectContext = [[FTAppDelegate sharedAppDelegate] managedObjectContext]; 

    NSError *error = nil; 
    [managedObjectContext save:&error]; 
    if (error) { 
     NSLog(@"error saving: %@",error); 
    } 

i uzyskać ten błąd:

2013-01-12 17:53:11.862 instacat[7000:907] Unresolved error Error Domain=NSCocoaErrorDomain Code=134030 "The operation couldn’t be completed. (Cocoa error 134030.)" UserInfo=0x2027b300 {NSAffectedObjectsErrorKey=(
"<Category: 0x1ed43cf0> (entity: Category; id: 0x1ed52970 <x-coredata://68E5D7B6-D461-4962-BC07-855349DB3263-7000-00000141BAB4C399/Category/tE8AB2F2E-C14C-4E93-8343-CC245B7726622> ; data: {\n categoryId = nil;\n isPrivate = 0;\n name = techies;\n users =  (\n );\n})" 
), NSUnderlyingException=Cannot update object that was never inserted.}, { 
    NSAffectedObjectsErrorKey =  (
     "<Category: 0x1ed43cf0> (entity: Category; id: 0x1ed52970 <x-coredata://68E5D7B6-D461-4962-BC07-855349DB3263-7000-00000141BAB4C399/Category/tE8AB2F2E-C14C-4E93-8343-CC245B7726622> ; data: {\n categoryId = nil;\n isPrivate = 0;\n name = techies;\n users =  (\n );\n})" 
    ); 
    NSUnderlyingException = "Cannot update object that was never inserted."; 
} 

Dziękuję za poświęcony czas i uwagę.

Używam AFIncrementalStore.

+0

Wygląda na to, że po raz pierwszy wstawiasz obiekt, nie jest on wstawiany do bazy danych. Postaraj się umieścić jakiś ciąg znaków, a następnie zaktualizuj go i mam nadzieję, że to rozwiąże Twój problem. – iCreative

+1

"' _category' "jest jak surowa część ivar nieruchomości. Jeśli jest to właściwość, co się dzieje, gdy używasz "self.category"? –

+0

Czy jesteś pewien, że to ten sam obiekt zarządzany? Identyfikator obiektu (adres URL 'x-coredata') wygląda jak tymczasowy identyfikator obiektu. 'T' jest gratisów. –

Odpowiedz

1

Po zaktualizowaniu obiektu, nie można używać insertNewObjectForEntityForName, trzeba najpierw zapisać swój przedmiot, a następnie wywołać coś takiego

[self.managedObjectContext refreshObject:_category mergeChanges:YES] 

Następnie użyj managedObjectContext zapisać ponownie.

Jest to różnica w bezpośrednim SQL jako "INSERT" i "UPDATE".

+0

To nie ma większego sensu.Obiekt managedObjectContext jest podobny do sesji w bazie danych i można wykonać wstawianie i aktualizację przed zatwierdzeniem, które jest odpowiednie w SQL dla odświeżenia. –

+0

Nie jestem pewien, co powiedzieć, musisz wywołać refreshObject, który to naprawi. Jest to zgodne z błędem: –

0

To, co myślę, że to się dzieje, to to, że nie otrzymujesz właściwego NSManagedObjectContext.

Pomyśl o tym jako o sesji. Więc kiedy aktualizujesz, nie dostajesz odpowiedniej sesji, więc twój obiekt tam nie istnieje.

Przed wykonaniem drugiego zapisu spróbuj znaleźć obiekt na tym obiekcie NSManagedObjectContext. Jeśli potrzebujesz dodatkowej pomocy, opisz, co dzieje się między utworzeniem a aktualizacją.

Niepoprawne NSManagedObjectContext może być spowodowane złym kodem w AppDelegate lub dostępem z innego wątku innego niż główny wątek.

4

Jak o coś takiego:

self.category.name = self.nameTextField.text; 

NSManagedObjectContext *managedObjectContext = [[FTAppDelegate sharedAppDelegate] managedObjectContext]; 

if(![self.category isInserted]) 
{ 
    [managedObjectContext insertObject:self.category]; 
} 

NSError *error = nil; 
[managedObjectContext save:&error]; 
if (error) { 
    NSLog(@"error saving: %@",error); 
} 

zasadzie sprawdzenia jest to obiekt został wstawiony wcześniej, jeśli nie, włóż go, a następnie zapisać kontekst.

+0

Wydaje się to być najbardziej poprawne, ponieważ musisz faktycznie użyć obiektu insertObject: w MOC z nowo utworzonym obiektem. – h4xnoodle

+0

@ h4xnoodle: [NSEntityDescription insertNewObjectForEntityForName: ... inManagedObjectContext: ...] robi obiekt insertObject w kontekście, więc nie musisz wywoływać go ręcznie. – JakubKnejzlik

1

Twój obiekt traci obiekt managedObjectContext. Użyć

self.managedObjectContext 

lub odśwież plik obiekt w

[[FTAppDelegate sharedAppDelegate] managedObjectContext] 

i edytować refetched obiekt, a następnie zapisać go.

+0

Czy możesz podać więcej szczegółów, dlaczego to pomaga? Lub, jeśli ktoś może się pomylić w pierwszej kolejności? – tslater

1

Mam ten sam błąd, ale inny i rzadki scenariusz, zdarza się raz w prawie 100 próbach. Znaleźć swoje problemu poniżej:

mam 2 NSManagedObjects w modelu danych rdzenia: 1- ołowiu 2- LeadAttirbute ołowiowych 1-M, związek o LeadAttribute.

Istnieje formularz wprowadzania danych ołowianych i odświeżania (tworzenie nowego potencjalnego klienta) po przesłaniu zgłoszenia.Jeśli nadal przesyłam sygnały na etapie, [managedObjectContext save: & error]; "Operacja nie mogła zostać zakończona (błąd Cocoa 134030.)": Rozpoczyna dając poniżej błędu

Domain = kod NSCocoaErrorDomain = 134030 = 0x1f251740 UserInfo {NSAffectedObjectsErrorKey = ( "(jednostka: LeadInfoAttribute; id: 0x1f2eb920; dane : {\ n attributeId = 0; \ n lead = nil; \ n optional = nil; \ n orderId = 0; \ n title = nil; \ n value = Bjjbjp; \ n}) " ), NSUnderlyingException = Can not zaktualizuj obiekt, który nigdy nie został wstawiony.}

I nadal daje ten sam błąd, dopóki nie kończę i ponownie uruchomić aplikację. Po wystąpieniu tego błędu nie mogę zaktualizować niczego w podstawowym modelu danych, więc moje pytania to:

1- Czy możemy usunąć stan błędu danych podstawowych? tj. przechwytywanie i usuwanie obiektu, który powoduje problemy, przed ponownym wywołaniem zapisu.

2- Jakie mogą być możliwe przyczyny tego problemu? Ponieważ jest bardzo rzadki i nie może odtworzyć tego za każdym razem.

+0

Mam ten sam problem. Jeśli znajdziesz rozwiązanie, daj mi znać. –

+0

Ja też .. Będę wyglądać i pisać, jeśli coś znajdę. – tslater

0

Właśnie napotkasz ten problem iw moim przypadku problem był następujący:

  • 1) utworzyć nowy obiekt zarządzany w kontekście A
  • 2) zapisać kontekście,
  • 3) odzyskać ten cel poprzez objectID z kontekstu B
  • 4) dokonać zmian na zarządzanego obiektu i zapisać kontekstowe B

Normalnie nie byłoby Probl em, ale w tym przypadku kontekst A jest kontekstem podrzędnym, a zatem nie zapisuje do magazynu trwałego (tylko do kontekstu nadrzędnego, który nie jest kontekstem B). Tak więc, gdy pobieranie dla obiektu zarządzanego odbywa się z kontekstu B, kontekst nie ma tego obiektu. Po wprowadzeniu zmian kontekst próbuje je mimo wszystko zachować ... i to w momencie wystąpienia tego błędu. W niektórych przypadkach (jak wspomniał o @Trausti Thor) metoda refreshObject: mergeChanges: może pomóc (przekazuje dane do innego kontekstu).

w twoim przypadku będę sprawdzić, czy:

1) udało kontekst obiektu z [[FTAppDelegate sharedAppDelegate] managedObjectContext] Zwraca zawsze tym samym kontekście

2) po zapisaniu kategorię, sprawdź, czy Naprawdę został zapisany do magazynu trwałego (self.category.objectID.isTemporaryID == NO)

UWAGA: Drugi punkt jest ważniejszy, ponieważ jeśli przyjrzysz się uważnie, twój obiekt kategorii nadal ma tymczasowy objectID, co oznacza, że ​​nie jest upierał się.