iPhone开发教程之Core Data 常见问题的总结

一、如果想把模拟其中保存的数据在真机中显示出来,可以在 AppDelegate 里用下面方法:

    模拟器保存完数据,然后进入目录:“用户名/Library/Application Support/iPhone Simulator/4.2/Applications/" 目录下,找到 p.sqlite,复制到软件的工程目录里。然后导入到工程里面,这样可以用模拟器里面保存的数据了。

- (NSManagedObjectModel *)managedObjectModel {
    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];   
    return managedObjectModel;
}
/**
Returns the persistent store coordinator for the application.
If the coordinator doesn't already exist, it is created and the application's store added to it.
*/
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }
    NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"p.sqlite"];
    /*
     Set up the store.
     For the sake of illustration, provide a pre-populated default store.
     */
    NSFileManager *fileManager = [NSFileManager defaultManager];
    // If the expected store doesn't exist, copy the default store.
    if (![fileManager fileExistsAtPath:storePath]) {
        NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"p" ofType:@"sqlite"];
        if (defaultStorePath) {
            [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
        }
    }
    NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];   
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
    NSError *error;
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
        // Update to handle the error appropriately.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }   
    return persistentStoreCoordinator;
}
//Returns the path to the application's documents directory.
- (NSString *)applicationDocumentsDirectory {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
    return basePath;
}

    二、常见错误 entityForName: could not locate an NSManagedObjectModel for entity name "Entity" 的解决方法:

    如果是如果是 AppDelegate.m 里面出现错误,需要这么写

    FavoriteViewController *favoriteVC = [[FavoriteViewController alloc] initWithNibName:nil bundle:nil];
    favoriteVC.managedObjectContext = self.managedObjectContext;

    如果是两个界面跳转,主要是出现在 iOS 4.0 以下版本,正确写法是:

Test.h

NSManagedObjectContext *managedObjectContext;
NextTest *next;

Test.m

next.managedObjectContext = self.managedObjectContext;
[self.navigationController pushViewController: next animated:YES];

错误写法:

NextTest *next = [[NextTest alloc] init];
next.managedObjectContext = self.managedObjectContext;
[self.navigationController pushViewController: next animated:YES];
[next release];

    三、条件过滤:

选择 cid=1 的数据

- (NSFetchedResultsController *)fetchedResultsController {
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"cid=1"];
    [fetchRequest setPredicate:predicate];
}

    四、通用代码,在 viewcontroller 里面会用到的。

TestViewController.h

@interface TestViewController : UITableViewController  <NSFetchedResultsControllerDelegate> {
    NSFetchedResultsController *fetchedResultsController;
    NSManagedObjectContext *managedObjectContext;
}
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
- (void)configureCell:(UITableViewCell *)cell withCategory:(Category *)category;
@end

TestViewController.m

#pragma mark -
#pragma mark fetchedResultsController
- (NSFetchedResultsController *)fetchedResultsController {
    if (fetchedResultsController != nil) {
        return fetchedResultsController;
    }
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Category" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];
    NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    NSArray *arraySortDescriptor = [[NSArray alloc] initWithObjects:nameDescriptor, nil];
    [fetchRequest setSortDescriptors:arraySortDescriptor];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:cidString];
    [fetchRequest setPredicate:predicate];
    NSFetchedResultsController *frController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                                                                   managedObjectContext:managedObjectContext
                                                                                     sectionNameKeyPath:@"name"
                                                                                              cacheName:@"Root"];
    frController.delegate = self;
    self.fetchedResultsController = frController;
    [frController release];
    [fetchRequest release];
    [nameDescriptor release];
    return fetchedResultsController;
}
- (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 NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] withCategory:anObject];
            break;
        default:
            break;
    }
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)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];
}

posted @ 2012-12-07 15:46  GreyWolf  阅读(243)  评论(0编辑  收藏  举报