2013-03-08 67 views
1

我创建用下面的代码的对象:的NSManagedObjectContext保存出现失去对象

+(Checkin *) newCheckinWithId:(NSString*) checkinID forVenueId:(NSString *)venueId 
{ 
    NSManagedObjectContext * context = [[AppDelegate sharedInstance] managedObjectContext]; 
    Checkin *ret = (Checkin *)[NSEntityDescription insertNewObjectForEntityForName:@"Checkin" inManagedObjectContext:context]; 
    ret.checkinID = checkinID; 
    ret.forVenueID = venueId; 
    ret.date = [NSDate date]; 
    NSError * error; 
    if(![context save:&error]) { 
     NSLog(@"Error saving!!!!!: %@", error.userInfo); 
    } 
    return ret; 
} 

并没有错误,但之后保存我再也瑟该对象的任何记录。

运行在此功能的调试器我看到它有1个对象unprocessedInserts后保存在上下文中的所有内部设置0的对象(我不知道如果多数民众赞成预期与否。

这里是代码中,我用它来创建我的商店+管理对象上下文(我用的一切1个上下文)它基本上都来自一个堆栈溢出后,我发现

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

    //NSArray *testArray = [[NSBundle mainBundle] URLsForResourcesWithExtension:@"momd"subdirectory:nil]; 

    NSString *path = [[NSBundle mainBundle] pathForResource:@"Model" ofType:@"momd"]; 

    if(!path) path = [[NSBundle mainBundle] pathForResource:@"Model" ofType:@"mom"]; 

    NSURL *modelURL = [NSURL fileURLWithPath:path]; 

    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 

    //__managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil]; 

    return _managedObjectModel; 
} 

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

    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]]; 
    NSPersistentStoreCoordinator *psc = _persistentStoreCoordinator; 

    // Set up iCloud in another thread: 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     // ** Note: if you adapt this code for your own use, you MUST change this variable: 
     NSString *iCloudEnabledAppID = @"[MY APP ID]"; 

     // ** Note: if you adapt this code for your own use, you should change this variable: 
     NSString *dataFileName = @"foursquareaugmentation.sqlite"; 

     // ** Note: For basic usage you shouldn't need to change anything else 

     NSString *iCloudDataDirectoryName = @"Data.nosync"; 
     NSString *iCloudLogsDirectoryName = @"Logs"; 
     NSFileManager *fileManager = [NSFileManager defaultManager]; 
     NSURL *localStore = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:dataFileName]; 
     NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil]; 

     if (iCloud) { 

      NSLog(@"iCloud is working"); 

      NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]]; 

      NSLog(@"iCloudEnabledAppID = %@",iCloudEnabledAppID); 
      NSLog(@"dataFileName = %@", dataFileName); 
      NSLog(@"iCloudDataDirectoryName = %@", iCloudDataDirectoryName); 
      NSLog(@"iCloudLogsDirectoryName = %@", iCloudLogsDirectoryName); 
      NSLog(@"iCloud = %@", iCloud); 
      NSLog(@"iCloudLogsPath = %@", iCloudLogsPath); 

      if([fileManager fileExistsAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]] == NO) { 
       NSError *fileSystemError; 
       [fileManager createDirectoryAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName] 
         withIntermediateDirectories:YES 
             attributes:nil 
              error:&fileSystemError]; 
       if(fileSystemError != nil) { 
        NSLog(@"Error creating database directory %@", fileSystemError); 
       } 
      } 

      NSString *iCloudData = [[[iCloud path] 
            stringByAppendingPathComponent:iCloudDataDirectoryName] 
            stringByAppendingPathComponent:dataFileName]; 

      NSLog(@"iCloudData = %@", iCloudData); 

      NSMutableDictionary *options = [NSMutableDictionary dictionary]; 
      [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption]; 
      [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption]; 
      [options setObject:iCloudEnabledAppID   forKey:NSPersistentStoreUbiquitousContentNameKey]; 
      [options setObject:iCloudLogsPath    forKey:NSPersistentStoreUbiquitousContentURLKey]; 

      [psc lock]; 
      NSError *error; 

      [psc addPersistentStoreWithType:NSSQLiteStoreType 
           configuration:nil 
             URL:[NSURL fileURLWithPath:iCloudData] 
            options:options 
             error:&error]; 

      if(error) 
      { 
       NSLog(@"Error adding persistent store %@, %@", error, [error userInfo]); 

       // comment in this line while debugging if get "Can't find model for source store" error in addPersistentStoreWithType. 
       // it means the sqlite database doesn't match the new model and needs to be created from scratch. 
       // this happens if you change the xcdatamodel instead of creating a new one under Xcode->Editor->Add Model Version... 
       // CoreData can only automatically migrate if there is a new model version (it can't migrate if the model simply changes, because it can't see the difference between the two models). 
       // be sure to back up the database if needed, because all data will be lost. 
       //[fileManager removeItemAtPath:iCloudData error:&error]; 

       /*// this is another way to verify the hashes for the database's model to make sure they match one of the entries in the momd directory's VersionInfo.plist 
       NSDictionary *sourceMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:[NSURL fileURLWithPath:iCloudData] error:&error]; 

       if(!sourceMetadata) 
       NSLog(@"sourceMetadata is nil"); 
       else 
       NSLog(@"sourceMetadata is %@", sourceMetadata);*/ 
      } 

      [psc unlock]; 
     } 
     else { 
      NSLog(@"iCloud is NOT working - using a local store"); 
      NSMutableDictionary *options = [NSMutableDictionary dictionary]; 
      [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption]; 
      [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption]; 

      [psc lock]; 
      NSError *error; 

      [psc addPersistentStoreWithType:NSSQLiteStoreType 
           configuration:nil 
             URL:localStore 
            options:options 
             error:nil]; 

      if(error) 
       NSLog(@"Error adding persistent store %@, %@", error, [error userInfo]); 
      [psc unlock]; 
     } 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      [[NSNotificationCenter defaultCenter] postNotificationName:@"SomethingChanged" object:self userInfo:nil]; 
     }); 
    }); 

    return _persistentStoreCoordinator; 
} 

/* 
Returns the managed object context for the application. 
If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application. 
*/ 
- (NSManagedObjectContext *) managedObjectContext 
{ 
    if (_managedObjectContext != nil) { 
     return _managedObjectContext; 
    } 

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

我一直工作在这个安静了一会儿,我出去的事情要尝试,所以任何帮助或调试步骤将不胜感激。(也不工作在icloud或本地)

也许我在提取错误,这就是为什么我没有得到对象。这里是我的提取:

+(NSArray *) checkinsForVenue:(NSString *) venueID 
{ 
    NSManagedObjectContext * context = [[AppDelegate sharedInstance] managedObjectContext]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Checkin" inManagedObjectContext:context]; 
    NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    request.entity = entity; 

    //NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(forVenueID = %@)", venueID]; 
    //request.predicate = predicate; 

    NSError *error; 
    NSArray * ret = [context executeFetchRequest:request error:&error]; 
    if(ret == nil) { 
     NSLog(@"%@", error.description); 
    } 
    return ret; 
} 

编辑:我问的是错误的问题。储蓄是工作获取不是。仍然无法弄清楚我的抓取有什么问题。

+0

也是我能想到的一切似乎正常Checkin * ret =(Checkin *)[NSEntityDescription insertNewObjectForEntityForName:@“Checkin”inManagedObjectContext:context];返回一个好的对象;上下文不是零,等不知道还有什么其他检查 – mike 2013-03-08 02:39:50

回答

1

你检查过它是否真的被持续到sqlite?

你的应用程序应该在~Library/Application Support/iPhone Simulator/6.1/Applications。您必须找到哪个应用程序文件夹是您的(它们都由UUIDS命名),然后在Documents文件夹中查找sql​​ite文件。在你的代码中,那将是foursquareaugmentation.sqlite

在该目录中打开一个终端窗口并启动sqlite3 foursquareaugmentation.sqlite开始查询数据库。

您应该找到一个名为ZCHECKIN的表(如果您有一个名为Checkin的托管对象类),并且每次保存上下文时,它都应该添加到该表中。

因此,在每次保存后运行select * from zcheckin;应该会向您显示一行添加到该表中。

如果没有发生这种情况,save操作中出现问题。如果它在数据库表中,则代码中的某些内容会丢失对象的引用,将其设置为nil或其他类似内容。

希望有所帮助。

+0

Thx的开始!我做到了,在表中找到1条,但是至少应该有20条。所以它必须一次工作,然后失败或什么。 但在代码中,我从来没有看到任何,即使是这个1,实际上有 – mike 2013-03-08 03:31:35

+0

啊等一下!我在我的实际电话上做了20个,是的,当我保存时它已经进入了数据库,那么一定是fletch出了问题呢?该提取仍返回0行。 – mike 2013-03-08 03:41:57

+0

嗯,你有没有尝试过使用调试器来检查NSArray从你的获取回来?您可以使用调试器的左侧窗格展开数组的内容并查看其中有多少个对象......或右键单击并打印内容。 我可能只是为了简化问题而剪掉iCloud代码,然后尝试在模拟器上敲入几行到核心数据并从那里检索它们。 – 2013-03-09 05:01:37

0

在我看来,你应该在createfetch中创建两个上下文。这将使核心数据感到困惑,并且不会从管理对象中获取最新的对象,尽管在insert new object successfully之后。

所以我建议你应该在两种方法之间传递上下文。至少,它适用于我。

相关问题