更改不会保存在核心数据模型中(例如删除对象)

时间:2014-07-15 13:09:36

标签: ios uitableview core-data save

我有一个tableviewcontroller,它显示Core Data模型的对象。我的导航栏中有一个按钮,单击它时会删除模型中的行和对象。出于测试目的,在AppDelegate中,我将具有2个属性的对象添加到仅模型实体。然后我在tableview中显示这个对象。在删除按钮上单击所选行已删除,我已将其设置为从数据模型中删除对象,但它不会保存更改。每次重建和运行应用程序时,都会添加更多内容,而当我删除它们时,更改将一直持续到下一次重建。如何在我的代码中修复此问题?

AppDelegate.h

#import <UIKit/UIKit.h>
#import "favTable.h"


@interface AppDelegate : UIResponder <UIApplicationDelegate> {

    NSManagedObjectContext *managedObjectContext;
    NSManagedObject *favoritesInfo;

}

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) favTable *viewController;
@property (strong, nonatomic) UINavigationController *navController;

@property (nonatomic, retain) NSManagedObject *favoritesInfo;
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;


- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory; // reference files for core data


@end

AppDelegate.m

#import "AppDelegate.h"


@implementation AppDelegate

@synthesize window = _window;
@synthesize viewController = _viewController;
@synthesize navController = _navController;

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
@synthesize favoritesInfo;



- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{



    NSManagedObjectContext *context = [self managedObjectContext];

    favoritesInfo = [NSEntityDescription
                                       insertNewObjectForEntityForName:@"FavoritesInfo"
                                       inManagedObjectContext:context];
    [favoritesInfo setValue:@"Product 1" forKey:@"name"];
    [favoritesInfo setValue:[NSNumber numberWithInt:15] forKey:@"score"];


    NSError *error;
    if (![context save:&error]) {
        NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
    }





    return YES;
}

// Core Data methods

- (void)saveContext{
    NSError *error = nil;
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }
}

- (NSManagedObjectContext *)managedObjectContext{
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        _managedObjectContext = [[NSManagedObjectContext alloc] init];
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return _managedObjectContext;
}

- (NSManagedObjectModel *)managedObjectModel{
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"DataModel" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"DataModel.sqlite"];

    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return _persistentStoreCoordinator;
}

#pragma mark - Application's Documents directory

// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}


@end

favtable.h

#import <UIKit/UIKit.h>



@interface favTable : UITableViewController  <NSFetchedResultsControllerDelegate> 
{
    NSFetchedResultsController *fetchedResultsController;
   NSManagedObjectContext *managedObjectContext;

    NSArray *favArr;
    NSMutableArray *favName;


}

@property (nonatomic, retain) NSArray *favArr;


@property (strong, nonatomic) ScannedProductControllerViewController *spVC;

@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;

@property (nonatomic, strong) NSMutableArray *favName;

@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;

@property (strong, nonatomic) ecoViewController *mainController;

@end

favtable.m

#import "favTable.h"
#import "AppDelegate.h"


@interface favTable ()

@end

@implementation favTable

@synthesize favArr;
@synthesize managedObjectContext;
@synthesize fetchedResultsController;
@synthesize favName;




- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.title = @"Favorites";


    self.navigationController.navigationBar.translucent = NO;

    UIBarButtonItem *delButton = [[UIBarButtonItem alloc]
                                  initWithTitle:@"Del"
                                  style: UIBarButtonItemStyleBordered
                                  target: self
                                  action:@selector(delItemToArray)];


    self.navigationItem.rightBarButtonItem = delButton;


    // passing the array of addedtofavorites to the total one with all favorites


    self.managedObjectContext = ((AppDelegate *) [UIApplication sharedApplication].delegate).managedObjectContext;



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

    fetchRequest.resultType = NSDictionaryResultType;

    [fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:@"name", nil]];



      NSError *error=nil;

    self.favArr=[[self.managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];


    if (error!=nil) {
        NSLog(@" fetchError=%@,details=%@",error,error.userInfo); 
    }


    self.favName = self.favName = [[self.favArr valueForKey:@"name"]mutableCopy];



}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
    // Return the number of rows in the section.
    return [favName count];;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{


    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell;

         // Configure the cell...

    cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell... setting the text of our cell's label

    cell.textLabel.text = [favName objectAtIndex:indexPath.row];

    return cell;
}



//Delete Item To Array
- (void)delItemToArray {

    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

    NSManagedObjectContext *context = [appDelegate managedObjectContext];

    AppDelegate *appDelegatee = (AppDelegate *)[[UIApplication sharedApplication] delegate];

    [context deleteObject:appDelegatee.favoritesInfo];

    NSIndexPath *indexPath;
    [favName removeObjectAtIndex:indexPath.row];

    [appDelegatee saveContext]; // to save changes

    NSError *error = nil;
    if (![context save:&error])
    {
        NSLog(@"Error deleting movie, %@", [error userInfo]);
    }

    [self.tableView reloadData];
}

1 个答案:

答案 0 :(得分:-1)

您的代码存在很多问题,我不知道从哪里开始。

班级名称应以大写字母开头 您在FavTable.m中为同一个app delegate singleton使用了两个变量 您正在声明变量indexPath而未初始化它 应该在NSFetchedResultsControllerDelegate方法中处理表视图的重新加载。 您显然没有使用获取的结果控制器。为什么? 你的可变数组favName有一个令人困惑的名字,导致普遍缺乏可读性 你写了self.favName = self.favName ......的达达主义语句 您的按钮处理程序方法名称delItemToArray同样具有冒险精神 favArr是一个不可变数组,但是你为它分配了一个可变数组 favNamefavArr是多余的,因为favArr已包含所有信息 您在删除期间修改favName但未对数据更改做出反应。 应用代表没有业务保留对favoritesInfo的引用 等......等等......

简而言之,你就是这样。在处理Objective-C和核心数据之前,您应该投入一些时间来获取一些基本的编程技能。