更新CoreData对象无法正常工作

地球王子

我是iOS开发/ CoreData的新手,已经搜索了针对我的特定问题的答案,但尚未找到答案。

我有一个TableView,其中包含来自数据库的一些对象。每个对象都有一个属性“名称”。如果我打开其中一个对象的详细信息视图,然后使用“后退”按钮返回tableView,则一切正常。如果我没有对“名称” TextField进行任何更改,然后按“完成”按钮返回到我的tableView,它也将起作用。我在“名称”文本字段中进行了一些更改后,立即收到以下错误消息:

无效的更新:部分0中的行数无效。更新(9)之后,现有部分中包含的行数必须等于更新(9)之前该部分中包含的行数,再加上或减去该数字从该部分插入或删除的行数(已插入0,已删除1),再加上或减去移入或移出该部分的行数(移入0,移出0)。

为什么要删除一个对象?

这是我的DetailsS​​taticTableViewController.m的代码:

#import "WeinStaticTableViewController.h"
#import "Wein.h"
#import "JSMToolBox.h"

@interface WeinStaticTableViewController ()

@end

@implementation WeinStaticTableViewController
@synthesize nameTextView;
@synthesize landTextView;
@synthesize herstellerTextView;
@synthesize wein = _wein;

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

- (void)viewDidLoad
{
   [super viewDidLoad];

   if (self.wein != nil) {
      self.nameTextView.text = self.wein.name;
   }
}

- (void) viewDidDisappear:(BOOL)animated
{
   [[JSMCoreDataHelper managedObjectContext] rollback];
   [super viewDidDisappear:animated];
}

- (void)didReceiveMemoryWarning
{
   [super didReceiveMemoryWarning];
   // Dispose of any resources that can be recreated.
   [self setNameTextView:nil];
   [self setLandTextView:nil];
   [self setHerstellerTextView:nil];
   self.wein = nil;
}

- (IBAction)barButtonItemDonePressed:(id)sender
{
   NSLog(@"%s", __PRETTY_FUNCTION__);
   if (self.wein != nil) {
       self.wein.name = self.nameTextView.text;
       [JSMCoreDataHelper saveManagedObjectContext:[JSMCoreDataHelper managedObjectContext]];
   }
   [self.navigationController popViewControllerAnimated:YES];
}
@end

这是我的JSMCoreDataHelper.m的代码:

#import "JSMCoreDataHelper.h"

@implementation JSMCoreDataHelper

+ (NSString*) directoryForDatabaseFilename
{
   return [NSHomeDirectory() stringByAppendingString:@"/Library/Private Documents"];
}

+ (NSString*) databaseFileName
{
   return @"database.sqlite";
}

+ (NSManagedObjectContext*) managedObjectContext
{
  static NSManagedObjectContext *managedObjectContext;
  if (managedObjectContext != nil) {
      return managedObjectContext;
  }

  NSError *error;
  // Verzeichnis unter dem das Datenbank-File abgespeichert werden soll, wird neu erzeugt, falls es noch nicht existiert.
  [[NSFileManager defaultManager] createDirectoryAtPath:[JSMCoreDataHelper directoryForDatabaseFilename] withIntermediateDirectories:YES attributes:nil error:&error];

  if (error) {
      NSLog(@"Fehler: %@", error.localizedDescription);
      return nil;
  }

  NSString *path = [NSString stringWithFormat:@"%@/%@", [JSMCoreDataHelper directoryForDatabaseFilename], [JSMCoreDataHelper databaseFileName]];
  NSURL *url = [NSURL fileURLWithPath:path];

  NSManagedObjectModel *managedModel = [NSManagedObjectModel mergedModelFromBundles:nil];

  NSPersistentStoreCoordinator *storeCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedModel];

  if (! [storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error]) {
      NSLog(@"Fehler: %@", error.localizedDescription);
      return nil;
  }

  managedObjectContext = [[NSManagedObjectContext alloc] init];
  managedObjectContext.persistentStoreCoordinator = storeCoordinator;

  return managedObjectContext;
}

+ (id) insertManagedObjectOfClass: (Class) aClass inManagedObjectContext: (NSManagedObjectContext*) managedObjectContext
{
   NSManagedObject *managedObject = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass(aClass) inManagedObjectContext:managedObjectContext];
   return managedObject;
}

+ (BOOL) saveManagedObjectContext: (NSManagedObjectContext*) managedObjectContext
{
   NSError *error;
   if (! [managedObjectContext save:&error]) {
       NSLog(@"Fehler: %@", error.localizedDescription);
       return NO;
   }
   return YES;
}

+ (NSArray*) fetchEntitiesForClass: (Class) aClass withPredicate: (NSPredicate*) predicate inManagedObjectContext: (NSManagedObjectContext*) managedObjectContext
{
   NSError *error;
   NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
   NSEntityDescription *entityDescription = [NSEntityDescription entityForName:NSStringFromClass(aClass) inManagedObjectContext:managedObjectContext];
   fetchRequest.entity = entityDescription;
   fetchRequest.predicate = predicate;

   NSArray *items = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
   if (error) {
       NSLog(@"Fehler: %@", error.localizedDescription);
       return nil;
   }
   return items;
}

+ (BOOL) performFetchOnFetchedResultsController: (NSFetchedResultsController*) fetchedResultsController
{
   NSError *error;
   if (! [fetchedResultsController performFetch:&error]) {
       NSLog(@"Fehler: %@", error.localizedDescription);
       return NO;
   }
   return YES;
}

@end

最后是我的MainTableViewController的numberOfSections和numberOfRowsInSection:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
   // Return the number of sections.
   return [[self.fetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
   // Return the number of rows in the section.
   return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
}

任何线索都可以帮助...谢谢!

曼弗雷迪

这是我的代码,使用NSFetchedResultsController,与您用于管理CoreData的代码配合得很好。

希望这可以帮助。

#import "Person.h"
#import "mainViewController.h"
#import "JSMCoreDataHelper.h"
#import "staticInfoViewController.h"

@implementation mainViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Load From CoreData
    NSError *error;
    if (![[self fetchedResultsController] performFetch:&error]) {
        // Update to handle the error appropriately.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }
}

#pragma mark - TableView DataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return [[self.fetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    [self configureCell:cell atIndexPath:indexPath];

    return cell;
}

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    Person *p = [_fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = [NSString stringWithFormat:@"Name: %@", p.name];
}

#pragma mark - TableView Delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    staticInfoViewController *info = [[staticInfoViewController alloc] initWithNibName:@"staticInfoViewController" bundle:[NSBundle mainBundle]];
    info.currentPerson = [_fetchedResultsController objectAtIndexPath:indexPath];
    [self.navigationController pushViewController:info animated:YES];
}

#pragma mark - Set NSFetchedResultsController

- (NSFetchedResultsController *)fetchedResultsController {

    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

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

    NSSortDescriptor *sort = [[NSSortDescriptor alloc]
                              initWithKey:@"name" ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

    [fetchRequest setFetchBatchSize:20];

    NSFetchedResultsController *theFetchedResultsController =
    [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                        managedObjectContext:[JSMCoreDataHelper managedObjectContext] sectionNameKeyPath:nil
                                                   cacheName:@"cache"];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;
}

#pragma mark - NSFetchedResultsController Delegate

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
    [self.tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {

    UITableView *tableView = self.tableView;

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray
                                               arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray
                                               arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
    [self.tableView endUpdates];
}

@end

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

更新无法正常工作

来自分类Dev

JavaScript对象无法正常工作

来自分类Dev

Mysqli更新无法正常工作

来自分类Dev

javascript对象引用无法正常工作

来自分类Dev

数组的对象类型的BubbleSort无法正常工作

来自分类Dev

fabric js:对象分组无法正常工作

来自分类Dev

更新后ServiceBusTrigger无法正常工作

来自分类Dev

更新文件无法正常工作

来自分类Dev

余烬更新后LinkTo无法正常工作

来自分类Dev

Netflix桌面在更新后无法正常工作

来自分类Dev

通过PHP的MySQL更新无法正常工作

来自分类Dev

NetBeans更新后无法正常工作

来自分类Dev

Xubuntu软件更新无法正常工作?

来自分类Dev

表单提交的Firebase更新无法正常工作?

来自分类Dev

NetBeans更新后无法正常工作

来自分类Dev

使用concat的MySQL更新无法正常工作

来自分类Dev

更新记录ajax jQuery无法正常工作

来自分类Dev

软件更新程序无法正常工作

来自分类Dev

余烬更新后LinkTo无法正常工作

来自分类Dev

使用PDO更新mysql无法正常工作

来自分类Dev

Windows 10“ ipconfig /更新”无法正常工作

来自分类Dev

Eclipse更新后无法正常工作

来自分类Dev

我的mysql更新查询无法正常工作

来自分类Dev

SQLite3:更新无法正常工作?

来自分类Dev

PDO和更新无法正常工作

来自分类Dev

Yii更新查询无法正常工作

来自分类Dev

更新时嵌入的AttributeOverride无法正常工作

来自分类Dev

更新面板时javascript无法正常工作

来自分类Dev

芝麻中的SPARQL更新无法正常工作