2012-09-19 4 views
6

가이가 괜찮 으면 좋겠어요.응용 프로그램을 다시 실행하면 데이터가 손실됩니다 (코어 데이터)

저는 iPhone 개발에 익숙하지 않습니다. 코어 데이터를 사용하여 간단한 응용 프로그램을 만들고 있습니다. 데이터를 저장할 때 응용 프로그램을 실행하는 동안 문제없이 작동하고 데이터를 검색 할 수 있습니다. 그러나 응용 프로그램을 다시 시작하면 모든 데이터가 손실됩니다.

응용 프로그램 시작시 ViewDidLoad 함수에서 작업중인 응용 프로그램에서 검색하는 것과 동일한 함수로 데이터를 검색하고 있습니다.

데이터 저장 방법 :

NSManagedObjectContext *context=[app managedObjectContext]; 
    Contacts *data=[NSEntityDescription insertNewObjectForEntityForName:@"Contacts" inManagedObjectContext:context]; 
    if(nameField.text.length <=0 || phoneField.text.length <=0) 
    { 

     UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"Warning!" message:@"Please enter some data." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil]; 
     [alert show]; 
    } 
    else 
    { 
     data.name = nameField.text; 
     data.phone = phoneField.text; 
     NSLog(data.name); 
     NSLog(data.phone); 
     [self.navigationController popToRootViewControllerAnimated:YES]; 

    } 

데이터를 검색하는 방법 :

NSEntityDescription *entity=[NSEntityDescription entityForName:@"Database" inManagedObjectContext:context]; 

    NSFetchRequest *fetchRequest=[[NSFetchRequest alloc]init]; 

    [fetchRequest setFetchBatchSize:20]; 

    [fetchRequest setEntity:entity]; 

    NSSortDescriptor *sorting = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; 

    NSArray *sorted_Array=[NSArray arrayWithObject:sorting]; 

    [fetchRequest setSortDescriptors:sorted_Array]; 

    NSError *error; 

    NSMutableArray *tArray=[[context executeFetchRequest:fetchRequest error:&error]mutableCopy]; 

    [self setArray:tArray]; 
    [self.tableView reloadData]; 

앱 위임 코드

#import "ZAppDelegate.h" 
#import "Contacts.h" 

@implementation ZAppDelegate 

@synthesize window = _window; 
@synthesize managedObjectContext = __managedObjectContext; 
@synthesize managedObjectModel = __managedObjectModel; 
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator; 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    // Override point for customization after application launch. 

    TableViewController *TVC=[[TableViewController alloc]init]; 

    TVC.MOcontext=self.managedObjectContext; 

    UINavigationController *nvgc=[[UINavigationController alloc]initWithRootViewController:TVC]; 
    self.window.rootViewController=nvgc; 


    self.window.backgroundColor = [UIColor whiteColor]; 
    [self.window makeKeyAndVisible]; 
    return YES; 
} 

- (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 
{ 
    // Saves changes in the application's managed object context before the application terminates. 
    [self saveContext]; 
} 

- (void)saveContext 
{ 
    NSError *error = nil; 
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext; 
    if (managedObjectContext != nil) 
    { 
     if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) 
     { 
      /* 
      Replace this implementation with code to handle the error appropriately. 

      abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
      */ 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      abort(); 
     } 
    } 
} 

#pragma mark - Core Data stack 

/** 
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] init]; 
     [__managedObjectContext setPersistentStoreCoordinator:coordinator]; 
    } 
    return __managedObjectContext; 
} 

/** 
Returns the managed object model for the application. 
If the model doesn't already exist, it is created from the application's model. 
*/ 
- (NSManagedObjectModel *)managedObjectModel 
{ 
    if (__managedObjectModel != nil) 
    { 
     return __managedObjectModel; 
    } 
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Diary" withExtension:@"momd"]; 
    __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 
    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; 
    } 

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

    NSError *error = nil; 
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 
    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) 
    { 
     /* 
     Replace this implementation with code to handle the error appropriately. 

     abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 

     Typical reasons for an error here include: 
     * The persistent store is not accessible; 
     * The schema for the persistent store is incompatible with current managed object model. 
     Check the error message to determine what the actual problem was. 


     If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory. 

     If you encounter schema incompatibility errors during development, you can reduce their frequency by: 
     * Simply deleting the existing store: 
     [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil] 

     * Performing automatic lightweight migration by passing the following dictionary as the options parameter: 
     [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; 

     Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details. 

     */ 
     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 

여기에 어떤 문제가 있습니까? 가능한 한 빨리 좋은 답변을 얻기를 바랍니다.

+1

게시 한 코드에서 절대'NSManagedObjectContext'라는 메시지를 보내지 않습니다. 그렇게 할 때까지 변경 사항은'NSPersistentStore'에 유지되지 않습니다. – FluffulousChimp

+0

@alanduncan : 재생 해 주셔서 감사합니다. NSPersistentStore에서 변경 사항을 어떻게 지속 할 수 있습니까? – iOmi

+0

야, 똑같은 일이 나에게 일어나고 있지만 VB.NET 및 DB = SQL Server 2012 Express의 콘솔 앱을 실행하는 Visual Studio 2012 및 EntityFramework를 사용하고 있습니다. 데이터는 .SaveChanges를 사용하여 저장됩니다 (각 루프가 다른 행을 쓰는 각 루프의 끝에서 실행 됨). 자, 내가 디버그 모드에서 응용 프로그램을 종료하면 데이터가 아직 남아 있습니다. 문제 없습니다. 그러나 IDE를 통해 디버그 모드에서 응용 프로그램을 다시 시작하면 마지막 응용 프로그램 실행 (마지막 실행 중에 저장된 데이터)에 기록 된 모든 데이터가 삭제되고 더 이상 존재하지 않습니다. 나를 미치게 만들어. 해결할 수 있었습니까? 이것을 읽는 누군가는 도울 수 있는가? –

답변

6

응용 프로그램의 수명주기에서 NSManagedObjectContextsave을 호출해야합니다. 그렇지 않으면 변경 사항이 NSPersistentStore에 유지되지 않습니다. 예를 들어 응용 프로그램 대리자의 applicationDidEnterBackground: 메서드에 있습니다.

NSError *saveError = nil; 
if(![[self managedObjectContext] save:&saveError]) { 
    // deal with error... 
} 

난 당신이 코드에 저장 가하고 있습니다 어디

+0

@aladuncan :: 나는 응용 프로그램의 수명주기 동안 버튼 동작에서 ** 저장 **을 호출하려고합니다. 좋지 않아? – iOmi

+0

그리고 'NSManagedObject' 컨텍스트를이 버튼 액션으로 저장 했더라도 데이터가 지속되지 않습니까? 일반적으로 응용 프로그램이 백그라운드로 들어갈 때 컨텍스트를 저장하려고합니다. 그렇지 않으면 사용자가 홈 버튼을 클릭하면 나중에 앱이 종료됩니다. 'save' 메서드의 결과를 검사하여 오류가 없는지 확인하고 있습니까? – FluffulousChimp

+0

@aladuncan :: 예! 나는 ** save ** 메소드를 체크하고, 브레이크 포인트를 놓고 라인별로 디버깅했다. 그것은 잘 작동합니다. 내 응용 프로그램이 시작될 때마다 ** Retreive ** 메서드가 호출되지만 아무 것도 제공하지 않습니다. 데이터가 저장되고 있는지 (지속되었는지) 데이터 파일에 저장되어 있는지를 확인할 수 없습니다. .NET과 마찬가지로 SQL Server를 사용하고 데이터베이스를 만들 때 SQL Server 데이터베이스 파일을 생성하여 데이터를 저장하는지 여부를 확인할 수있는 파일 크기를 계산합니다. 그래서 iOS에서는 .NET과 같은 것이 없습니까? – iOmi

0

을 볼 수 없습니다 ... 응용 프로그램 대리자를 설정하고 애플 템플릿처럼 코어 데이터 스택 유지하고 있으리라 믿고있어. 저장하려면 managedcontext에 알려줘야합니다. 당신이하는 일은 앱과 디자인에 달려 있습니다. 어딘가에 이미 앱에 있다고 생각된다면 NSLog를 추가하여 디버깅하거나 디버거 도구를 사용하여 실제로 코드를 실행하십시오.

쉬운 수정입니다. 행운을 빕니다. AppDelegate에에서

+0

** 나는 ** NSLog ** 및 디버거 도구를 사용했습니다. 응용 프로그램은 실행 중일 때 작동하며 데이터를 저장하고 데이터를 검색하지만 다시 시작하면 모든 데이터가 사라집니다. – iOmi

+1

NSPersistant 저장소의 변경 사항은 일반적으로 응용 프로그램 delegate.m에 있습니다. 그리고 위와 같이 다른 사람이 컨텍스트에 저장할 때 app delegate.m 파일을 사용하여 저장합니다. app delegate.m 파일뿐만 아니라 명시 적으로 저장하는 위치에 코드를 표시 하시겠습니까? 도움을주고 싶지만 두 코드에서 코드를 볼 필요가 있습니다. 좋은 직장은 NSLog ..를 사용하여 디버거뿐만 아니라 디버거를 사용하는 좋은 방법입니다. 계속 올려! – holster

+0

:: 답변 해 주셔서 감사 드리며 늦게 늦어서 죄송합니다. ** appDelegate.m ** 코드로 내 질문을 업데이트했습니다. ** appDelegate.m ** 부분을 살펴보십시오. 그리고 내가 명시 적으로 저장하는 부분은 질문에서 이미 언급 한 ** 데이터 저장 방법 **입니다. – iOmi

4

:

- (void)applicationWillTerminate:(UIApplication *)application 
{ 
    // Saves changes in the application's managed object context before the application terminates. 
    [self saveContext]; 
} 

-saveContext은 엑스 코드의 템플릿의 이전 버전에서 -save 수 있습니다.


그리고 무엇보다, 당신은 단지 다른 클래스에서 -save 또는 -saveContent 메서드를 호출 할 수 있습니다

[(AppDelegate *)[UIApplication sharedApplication] saveContext]; 
0

NSManagedObjectContext 스크래치 패드를 제공합니다 : 당신이 당신의 개체를 원하는대로 당신이 할 수 있지만, 결국 그것을 구해야합니다. NSManagedObjectContext에 대한 모든 변경은 저장할 때까지 일시적입니다. 당신의 방법의 끝이 추가보십시오 :

if (![context save:&error]) { 
NSLog(@"Couldn't save: %@", error); 
} 
0

이 Context가
CoreDataManager를 저장할 필요가 * 컨텍스트 = [CoreDataManager sharedInstance]
...
..
...
...
.....
...
[컨텍스트 saveContext];

관련 문제