iOS CoreData объект обновления объекта - PullRequest
3 голосов
/ 28 мая 2011

Я внедряю диспетчер автомобилей для приложения для iPhone, и у меня возникают проблемы с сохранением новой машины.Таким образом, у меня есть сущность "Car" (и загруженная БД), содержащая несколько атрибутов.У меня есть 2 логических значения «сохранено» и «выбрано», чтобы отслеживать, какой автомобиль пользователь добавил в свой список (если он добавлен, сохранен = 1) и какой автомобиль выбран в данный момент.Поэтому, когда я создаю новый автомобиль, я отменяю выбор старого (selected = 0) и хочу изменить новый автомобиль, чтобы установить его атрибуты Saved = 1 и selected = 1.

Вот мои функции:

- (IBAction)save
{
    // Disable the previous car selection.
    [self deselectCurrentSelectedCar];

    // Add new car as saved and selected.
    [self saveAndSelectNewCar];

    // Call the delegate to dismiss the modal view.
    [_delegate dismissAndSave];
}

- (void)deselectCurrentSelectedCar
{    
    // Fetched saved car.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:entity];

    // Set predicate and sort orderings...
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"selected = 1"];
    [fetchRequest setPredicate:predicate];

    // Execute the fetch -- create a mutable copy of the result.
    NSError *error = nil;
    NSMutableArray *mutableFetchResults = [[self.managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];
    if (mutableFetchResults == nil) {
        // Handle the error.
        NSLog(@"[AddCarViewController] deselect car: car not found.");
    }
    else {
        // Get car and assign new selected value.
        Car *carToSave = (Car *)[mutableFetchResults objectAtIndex:0];
        [carToSave setSelected:[NSNumber numberWithInt:0]];

        // Save the car.
        NSError *error = nil;
        if (![self.managedObjectContext save:&error]) {
            // Handle the error.
            NSLog(@"[AddCarViewController] deselect car: error saving car.");
        }
        else {
            NSLog(@"[AddCarViewController] deselect car: car saved.");
        }
    }

    // Memory management.
    [fetchRequest release];
    [mutableFetchResults release];
}
- (void)saveAndSelectNewCar
{
    // Get the car, and pass to the delegate the new settings.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:entity];

    // Set predicate and sort orderings...
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(year=%@) AND (make=%@) AND (model=%@) AND (d=%@) AND (n=%@)", _car.year, _car.make, _car.model, _car.d, _car.n];
    [fetchRequest setPredicate:predicate];

    // Execute the fetch -- create a mutable copy of the result.
    NSError *error = nil;
    NSMutableArray *mutableFetchResults = [[self.managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];
    if (mutableFetchResults == nil) {
        // Handle error.
        NSLog(@"[AddCarViewController] save and select: can't save the new car");
    }
    else {
        // Get the car selected.
        Car *selectedCar = (Car *)[mutableFetchResults objectAtIndex:0];
        [selectedCar setValue:[NSNumber numberWithInt:1] forKey:@"selected"];
        [selectedCar setValue:[NSNumber numberWithInt:1] forKey:@"saved"];

        // Save the car.
        NSError *error = nil;
        if (![self.managedObjectContext save:&error]) {
            // Handle the error.
            NSLog(@"[AddCarViewController] save and select: error saving car.");
        }
        else {
            NSLog(@"[AddCarViewController] save and select: car saved.");
        }

        // Add car to delegate.
        [EcoAppAppDelegate setUserCar:selectedCar];
    }

    // Memory management.
    [fetchRequest release];
    [mutableFetchResults release];
}

И у меня все время есть этот журнал: «ошибка сохранения автомобиля».на обе функции.Так что определенно что-то не так.

Кроме того, довольно неприятно выбирать машину, которую я хочу изменить, вместо того, чтобы сразу же делать обновление.Если есть другой, пожалуйста, скажите мне!

Спасибо.

1 Ответ

3 голосов
/ 28 мая 2011

В вашем заголовочном файле вы должны настроить изменяемый массив для ваших машин.

NSMutableArray *carArray;

и

@property (nonatomic, retain) NSMutableArray *carArray;

Затем обязательно синтезируйте его в файле реализации.Затем, когда вы извлекаете данные из контекста управляемого объекта, вы можете установить свой массив с возвращенным содержимым

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:[self managedObjectContext]];
[fetchRequest setEntity:entity];

// Execute the fetch -- create a mutable copy of the result.
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[self.managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];
if (mutableFetchResults == nil) {
    // Handle the error.
    NSLog(@"[AddCarViewController] deselect car: car not found.");
} else {
    [self setCarArray:mutableFetchResults];
}

. Это сделает все объекты в контексте управляемого объекта, поэтому, когда вы захотите изменить автомобиль, вы можете найти его там вместо того, чтобы искать снова.Если вам нужно его отсортировать, вы можете применить дескриптор сортировки, инициализированный одним из ваших атрибутов в качестве ключа.Например:

NSSortDescriptor *sorter = [NSSortDescriptor sortDescriptorWithKey:@"selected" ascending:YES];
[carArray sortUsingDescriptors:[NSArray arrayWithObject:sorter]];

Это позволит отсортировать автомобили в зависимости от того, выбраны они или нет.

Что касается причин возникновения ошибки, это может быть одной из многих причин.Обычно MOC не может сохранить, если один из ваших атрибутов установлен в nil, так что это может быть причиной.Вы можете получить некоторые подробности из этого, если вы установите что-то вроде следующего:

if (![self.managedObjectContext save:&error]) {
    NSLog(@"failed with error %@", error);
}

Это вернет фактическую ошибку, с которой вы столкнулись.Также было бы неплохо настроить журнал, чтобы убедиться, что у вас указан автомобиль.Что-то вроде NSLog(@"selected car %@", carToSave); просто чтобы быть в безопасности

...