Core Data Saving Attributes Of Entities

2019-08-03 16:51发布

问题:

This question is about Core Data.

I created a Entity called TV with three attributes called name, price and size. I also created a subclass of NSMutableObject with TV.h and TV.m files.

I imported the TV.h to my DetailViewController.h which handles my sliders und UIElements I want to take the values of.

So I did a fetch request, and everything works fine, BUT:

Everytime I update the UISlider (valueDidChange:), Xcode creates a COPY of my entity and adds it to my TV-Object.

All I want Xcode is just to edit and save to the current entity, not to edit and save in a new entity.

Help is very appreciated!

Thank you in advance.

My Code:

DetailViewController.m

- (IBAction)collectSliderValue:(UISlider *)sender {

if (__managedObjectContext == nil) {
    NSLog(@"Problem ...");
    __managedObjectContext = [(MasterViewController *)[[UIApplication sharedApplication] delegate] managedObjectContext];
    NSLog(@"... solved!");
}

if (sender == sizeSlider) {

    NSError *error = nil;

    NSManagedObjectContext *context = [self managedObjectContext];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"TV" inManagedObjectContext:context];
    [fetchRequest setEntity:entity];
    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];

    TV * currentTV = [[TV alloc] initWithEntity:entity insertIntoManagedObjectContext:context];

    currentTV.size = [[NSNumber alloc] initWithInt:(sender.value + 0.5f)];
    currentTV.name = @"New TV!";

    NSError *error11;
    [__managedObjectContext save:&error11];

    for (NSManagedObject *info in fetchedObjects)
    {
        NSLog(@"Name = %@", [info valueForKey:@"name"]);
        NSLog(@"Size = %@", [info valueForKey:@"size"]);
        NSLog(@"Price = %@", [info valueForKey:@"price"]);
    }
    [fetchRequest release];
}

回答1:

//Editing begins ...     
TV * currentTV = [[TV alloc] initWithEntity:entity insertIntoManagedObjectContext:context]; 

Editing doesn't begin, you are creating a new object right there. Your view controller needs an instance variable to hold the current TV entity that you are modifying.

From the template project you have created, the variable detailItem contains the managed object that you are currently editing. You should specifically set this as a TV object, and refer to this instead of currentTV in your detailViewController code. You must remove all of the fetch request and managed object context code - this is not relevant in your detail view controller, it should be managed by the master view controller.

So, in DetailViewController.h:

@property (strong, nonatomic) id detailItem;

becomes

@property (strong, nonatomic) TV detailItem;

And in your collectSliderValue method, it should look something much more simple like this:

- (IBAction)collectSliderValue:(UISlider *)sender 
{

    if (sender == sizeSlider) 
        self.detailItem.size = [NSNumber numberWithFloat:sender.value];    
}

The saving of the managed object context shouldn't occur until back in your detail view controller, this is taken care of in your application delegate.

In your master detail controller .m file you may also need to import the TV.h file so that it knows that TV is a NSManagedObject subclass. Also, cast to TV when you are setting the detail item:

self.detailViewController.detailItem = (TV*)selectedObject;