0

我有这本关于核心数据的书。我在我的第二章,我正在关注一个正在进行的项目。该项目增加了一个组织和三名员工。其中一名员工是领导。我已成功执行这些步骤,虽然有 4 个警告但没有错误。我知道这应该可行,因为在重新安装 OSX 之前我有同样的项目。

AppDelegate.h

#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>

@class ViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) ViewController *viewController;

//Core Data Implementation
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;

//Display Person
- (void)readData;
- (void)displayPerson:(NSManagedObject *)person withIndentation:(NSString *)indentation;

@end

AppDelegate.m

#import "AppDelegate.h"

#import "ViewController.h"

@implementation AppDelegate

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

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [self createData];
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

#pragma mark - Create Data

-(void)createData
{
    NSManagedObject *organization = [NSEntityDescription insertNewObjectForEntityForName:@"Organization" inManagedObjectContext:self.managedObjectContext];
    [organization setValue:@"Company, Inc." forKey:@"name"];
    [organization setValue:[NSNumber numberWithInt:[@"Company, Inc." hash]] forKey:@"id"];

    NSManagedObject *john = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext];
    [john setValue:@"John" forKey:@"name"];
    [john setValue:[NSNumber numberWithInt:[@"John" hash]] forKey:@"id"];

    NSManagedObject *jane = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext];
    [jane setValue:@"Jane" forKey:@"name"];
    [jane setValue:[NSNumber numberWithInt:[@"Jane" hash]] forKey:@"id"];

    NSManagedObject *bill = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext];
    [bill setValue:@"Bill" forKey:@"name"];
    [bill setValue:[NSNumber numberWithInt:[@"Bill" hash]] forKey:@"id"];

    NSMutableSet *johnsEmployees = [john mutableSetValueForKey:@"employees"];
    [johnsEmployees addObject:jane];
    [johnsEmployees addObject:bill];
}

- (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();
        }
    }
}

#pragma mark - Core Data stack

- (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:@"Core01" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

    return _managedObjectModel;
}

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

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Core01.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

- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

#pragma mark - Display Person

- (void)displayPerson:(NSManagedObject*)person withIndentation:(NSString*)indentation {
    NSLog(@"%@Name: %@", indentation, [person valueForKey:@"name"]);
    indentation = [NSString stringWithFormat:@"%@   ", indentation];
    NSSet *employees = [person valueForKey:@"employees"];
    id employee;
    NSEnumerator *it = [employees objectEnumerator];

    while ((employee = [it nextObject]) != nil) {
        [self displayPerson:employee withIndentation:indentation];
    }
}

- (void)readData {
    NSManagedObjectContext *context = [self managedObjectContext];
    NSEntityDescription *orgEntity = [NSEntityDescription entityForName:@"Organization" inManagedObjectContext:context];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:orgEntity];
    NSArray *organizations = [context executeFetchRequest:fetchRequest error:nil];
    id organization;
    NSEnumerator *it = [organizations objectEnumerator];

    while ((organization = [it nextObject]) != nil) {
        NSLog(@"Organization: %@", [organization valueForKey:@"name"]);
        NSManagedObject *leader = [organization valueForKey:@"leader"];
        [self displayPerson:leader withIndentation:@"   "];
    }
}
- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

这些是唯一对项目很重要的代码。是的,这是一个非常简单的 Core Data 应用程序。

书中有使用 sqlite3 访问数据库的指南。

在 Terminal.app 中:

Input: cd ~/Library/Application\ Support/iPhone\ Simulator
Input: find . -name "Core01.sqlite" –print
Output: ./6.0/Applications/25DB9FAD-6921-4791-9409-FF84F275D8A8/Documents/Core01.sqlite
Input: sqlite3 ./6.0/Applications/25DB9FAD-6921-4791-9409-FF84F275D8A8/Documents/Core01.sqlite

在 sqlite3 中:

Input: sqlite> select Z_PK, ZID, ZLEADER, ZNAME from ZORGANIZATION;
Output: 1|-19904|2|Company, Inc.

Input: sqlite> select Z_PK, ZID, Z2EMPLOYEES, ZNAME from ZPERSON;
Output:
1|6050|2|Jane
2|-28989||John
3|28151|2|Bill

问题是,数据库是空的。我知道出了什么问题,也没有我想念什么。

4

2 回答 2

2

我认为问题是您需要-(void)saveContext在设置所有数据后调用该方法-(void)createData

试试这个:

-(void)createData
{
    NSManagedObject *organization = [NSEntityDescription insertNewObjectForEntityForName:@"Organization" inManagedObjectContext:self.managedObjectContext];
    [organization setValue:@"Company, Inc." forKey:@"name"];
    [organization setValue:[NSNumber numberWithInt:[@"Company, Inc." hash]] forKey:@"id"];

    NSManagedObject *john = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext];
    [john setValue:@"John" forKey:@"name"];
    [john setValue:[NSNumber numberWithInt:[@"John" hash]] forKey:@"id"];

    NSManagedObject *jane = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext];
    [jane setValue:@"Jane" forKey:@"name"];
    [jane setValue:[NSNumber numberWithInt:[@"Jane" hash]] forKey:@"id"];

    NSManagedObject *bill = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext];
    [bill setValue:@"Bill" forKey:@"name"];
    [bill setValue:[NSNumber numberWithInt:[@"Bill" hash]] forKey:@"id"];

    NSMutableSet *johnsEmployees = [john mutableSetValueForKey:@"employees"];
    [johnsEmployees addObject:jane];
    [johnsEmployees addObject:bill];

    [self saveContext];
}
于 2013-01-23T16:10:07.300 回答
1

除非我在代码中遗漏了它,否则您调用 [self createData]; 但永远不要保存上下文。

在 createData 方法的末尾,添加 [self saveContext]; 称呼。

于 2013-01-23T16:09:06.723 回答