2009-09-17 19 views
10

W moim projekcie iPhone, chcę napisać funkcję, która sprawdza, czy istnieje obiekt w moim Core Data ManagedObjectContext o danej wartości dla określonej właściwości, na przykład some_property.Pobierz obiekt według właściwości w Core Data

Jeśli istnieje już obiekt z some_property == 12, chcę, aby funkcja zwróciła obiekt, w przeciwnym razie chcę utworzyć obiekt, lub przynajmniej wrócić nil.

Jak to zrobić?

Odpowiedz

19

Poniższy fragment pokazuje, jak odzyskać obiekty pasujące do określonego predykatu. Jeśli nie ma takich obiektów, urywek pokazuje, jak utworzyć nowy obiekt, zapisać go i zwrócić.

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"YourEntityName" inManagedObjectContext:managedObjectContext]; 
    [request setEntity:entity]; 
    // retrive the objects with a given value for a certain property 
    NSPredicate *predicate = [NSPredicate predicateWithFormat: @"property == %@", value]; 
    [request setPredicate:predicate]; 

    // Edit the sort key as appropriate. 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"yourSortKey" ascending:YES]; 
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 
    [request setSortDescriptors:sortDescriptors]; 



    // Edit the section name key path and cache name if appropriate. 
    // nil for section name key path means "no sections". 
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"]; 
    aFetchedResultsController.delegate = self; 

    NSError *error = nil; 
    NSArray *result = [managedObjectContext executeFetchRequest:request error:&error]; 

    [request release]; 
    [sortDescriptor release]; 
    [sortDescriptors release]; 


    if ((result != nil) && ([result count]) && (error == nil)){ 
     return [NSMutableArray arrayWithArray:result]; 
    } 
    else{ 
     YourEntityName *object = (YourEntityName *) [NSEntityDescription insertNewObjectForEntityForName:@"YourEntityName" inManagedObjectContext:self.managedObjectContext]; 
      // setup your object attributes, for instance set its name 
      object.name = @"name" 

      // save object 
      NSError *error; 
      if (![[self managedObjectContext] save:&error]) { 
      // Handle error 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 

      } 

      return object; 

    } 
+0

wow, to było szybkie! Pozwól mi po prostu wypróbować to ... – winsmith

+0

Jaki jest sens 'aFetchedResultsController'? Czy myliłem się myśląc, że go stworzyłeś, ale potem nigdy go nie używałeś? – ArtOfWarfare

+0

Masz rację, w tym konkretnym przykładzie NSFetchedResultsController nie jest używany, ale powinien być w kontekście prawdziwej aplikacji (upraszcza wiele innych rzeczy i zapewnia miły mechanizm buforowania). –

2

Lepiej jest, jeśli nie wykonujesz wielokrotnego pobierania, jeśli chcesz sprawdzić pewne właściwości na danych lokalnych. Po prostu wykonaj jedno żądanie pobierania, używając wstępnie wypełnionej tablicy, a następnie powtórz lub odfiltruj wyniki.

jest to fragment kodu z danych Core Programming Guide "wykonawcze Find-or-Tworzenie Skutecznie":

// get the names to parse in sorted order 
NSArray *employeeIDs = [[listOfIDsAsString componentsSeparatedByString:@"\n"] 
     sortedArrayUsingSelector: @selector(compare:)]; 

// create the fetch request to get all Employees matching the IDs 
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease]; 
[fetchRequest setEntity: 
     [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:aMOC]]; 
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"(employeeID IN %@)", employeeIDs]]; 

// make sure the results are sorted as well 
[fetchRequest setSortDescriptors: [NSArray arrayWithObject: 
     [[[NSSortDescriptor alloc] initWithKey: @"employeeID" 
       ascending:YES] autorelease]]]; 
// Execute the fetch 
NSError *error; 
NSArray *employeesMatchingNames = [aMOC 
     executeFetchRequest:fetchRequest error:&error];