2013-01-12 15 views
7

Moja aplikacja iOS wykorzystuje dane podstawowe za pośrednictwem wielu wątków. Otrzymuję niektóre raporty o awariach z następującym komunikatem: "NSObjectInaccessibleException", powód: "CoreData nie może spełnić błędu dla" 0x1e07a9b0 ""NSObjectInaccessibleException ', powód: "CoreData nie może spełnić błędu

Rozumiem, co powoduje ten problem - że obiekt został usunięty, ale inny wątek Próbuję uzyskać do niego dostęp. Pracuję nad rozwiązaniem problemu, ale chcę dodać czek w wątku tła, aby zobaczyć, czy obiekt będzie w ten sposób zakłócać.

Mój kod w tej chwili odnosi się do myObject.myValue. możliwe sprawdzenie, takie jak:

if (!myObject.myValue) { 
    return; 
} 

... tak, aby uzyskać z czy przed wykonaniem czegokolwiek, co mogłoby spowodować taką awarię? Lub po prostu wywołanie myObject.myValue, nawet, aby zobaczyć, czy jest null, powodują taki wyjątek być wyrzucony?

+8

Przy okazji, masz bardzo niską akceptację odpowiedzi, prawdopodobnie dlatego nikt nie chce odpowiedzieć na twoje pytania. Rozważ przeanalizowanie starych pytań i wybranie prawidłowej odpowiedzi dla każdego z nich. http://stackoverflow.com/users/353137/jason?tab=questions – iwasrobbed

Odpowiedz

19

można spróbować i skorzystać existingObjectWithID:error::

Zwraca obiekt dla określonego identyfikatora.

- (NSManagedObject *)existingObjectWithID:(NSManagedObjectID *)objectID error:(NSError **)error 

Dyskusja

Jeśli nie jest zarządzany obiekt o podanym ID już zarejestrowany w kontekście, że obiekt jest zwracany bezpośrednio; w przeciwnym razie odpowiedni obiekt zostanie zakwestionowany w kontekście.

Ta metoda może wykonywać operacje wejścia/wyjścia, jeśli dane są nieokreślone.

W przeciwieństwie do objectWithID: ta metoda nigdy nie zwraca błędu.

można zrobić:

if ([myMOC existingObjectWithID:myObject.objectID error:&error]) 
    ... 
5

Należy upewnić się, że obiekt istnieje przed uzyskaniem dostępu jest zmienne, jeśli masz problemy, gdy przedmiot może zostać usunięte w innym wątku.

dwa sposoby:

  1. odświeżyć widok źródeł danych zawsze, gdy dane są usuwane. Możesz to zrobić, rejestrując się w powiadomieniu NSManagedObjectContextObjectsDidChangeNotification, a następnie analizując userInfo w tym powiadomieniu, aby zobaczyć, który obiekt został usunięty.
  2. Użyj kodu podobnego do poniższego, gdy przekazujesz dane do wielu wątków.

Przykład:

// Cache and pass the object's ID off to another thread to do work on 
// You can just store it as a property on the class 
@try { 
    NSManagedObject *theObject = [managedObjectContext objectWithID:self.theObjectID]; 

    // do stuff with object 
} 
@catch (NSException * e) { 
    // An entity with that object ID could not be found (maybe they were deleted) 
    NSLog(@"Error finding object: %@: %@", [e name], [e reason]); 
} 
+0

Metoda nr 1, zdecydowanie. Mogę czekać na powiadomienia w widoku "szczegółowym" (dostępnym przed/podczas synchronizacji) i wyłączać wszelkie funkcje, które współdziałają z obiektem, powiadamiać o tym użytkownika itp. – Mark

0

Można sprawdzić [myObject isFault] gdzie myObject jest NSManagedObject instancja

+0

Sam fakt, że obiekt jest błędem, nie oznacza, że ​​dostęp każda z jego właściwości rzuci ten wyjątek. Zwykle spowoduje to tylko załadowanie danych ze składnicy danych. Wyjątek jest zgłaszany tylko wtedy, gdy obiekt ten już nie istnieje w składnicy danych, a zatem nie można go załadować (a.k.a. "faulted"). –

2

można sprawdzić NSManagedContext jest istniał podczas korzystania z NSManagedObject. w ten sposób:

if (obj.managedObjectContext) 
{ 
    //do things 
} 
+0

Miałem tę samą myśl, jednak nie mogę znaleźć żadnej dokumentacji potwierdzającej to zachowanie. Czy ktokolwiek może potwierdzić, że jest to definitywny sposób sprawdzenia, czy obiekt jest nadal dostępny? –

Powiązane problemy