2015-08-27 23 views
0

當我的應用程序終止/進入後臺時,我想將NSMutableArray保存爲Core-Data,我想在應用程序啓動/激活時加載NSMutableArray。我不太瞭解Core-Data。這是我第一次使用它。我看了一大堆視頻,教程,之前的Stackoverflow問題和Apple的文檔。我認爲我想要做的是屬於Apple Core-Data文檔中的Non-Standard Persistent Attributes章節。在覈心數據中存儲和提取NSMutableArray

我已經建立了一個名爲TableViewList的實體,並給它一個名爲List可變形的屬性。

這是我的AppDelegate.h和.m代碼。所有的建議都會很棒。

AppDelegate.h
#import <UIKit/UIKit.h> 
#import "TableViewController.h" 

@interface AppDelegate : UIResponder <UIApplicationDelegate> 

@property (strong, nonatomic) UIWindow *window; 

@property(nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; 
@property(nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; 
@property(nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; 

-(NSString *) applicationDocumentsDirectory;  
@end 

AppDelegate.m
#import <CoreData/CoreData.h> 
#import "AppDelegate.h" 
#import <UIKit/UIKit.h> 

@interface AppDelegate() 

@end 

@implementation AppDelegate 
@synthesize managedObjectModel; 
@synthesize managedObjectContext; 
@synthesize persistentStoreCoordinator; 
- (void)applicationDidEnterBackground:(UIApplication *)application { 

    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; 

    NSManagedObjectContext *context = [appDelegate managedObjectContext]; 
    NSManagedObject *newContact; 
    newContact = [NSEntityDescription insertNewObjectForEntityForName:@"TableViewList" inManagedObjectContext:context]; 
    NSData *arrayData = [NSKeyedArchiver archivedDataWithRootObject:ListArray];   
    [newContact setValue:arrayData forKey:@"list"]; 
    NSError *error = nil;   
    [context save:&error]; 


} 

- (void)applicationDidBecomeActive:(UIApplication *)application { 
    NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:[NSBundle allBundles]]; 
    NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; 
    NSURL *url = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent: @"App1.sqlite"]; 
    [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:nil]; 
    managedObjectContext = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType]; 
    managedObjectContext.persistentStoreCoordinator = coordinator; 


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

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"TableViewList" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 
    NSError *error = nil; 
    NSArray *result = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

    if (error) { 
     NSLog(@"unable to execute fetch request"); 
     NSLog(@"%@, %@", error, error.localizedDescription); 
    } 
    else 
     NSLog(@"%@",result); 
} 

結果陣列返回一個空數組。我不認爲我正在保存並正確提取陣列。在此先感謝您的幫助!

我用this link在我的對象中實現了NSCoding

+0

有兩個問題:1.數據模型中'list'屬性的類型是什麼? 2.您正在保存的陣列中有哪些對象? –

+0

@TomHarrington 1.'list'是類型可轉換的。 2.該對象是一個具有三個屬性的自定義NSObject。兩個是NSString,一個是NSUInteger。 – njyulan

+0

您確定要/需要使用Transformable嗎?您似乎將列表存儲爲單個對象上的單個屬性。您可以改爲擁有兩個字符串屬性和一個整數的實體,併爲數組中的每個對象另存一個該實體的實例。 – pbasdf

回答

3

確定有幾件事情要在這裏提到:

  1. applicationDidEnterBackground,該方法的前半部分配置,你從來沒有使用新的管理對象上下文。由於您從應用程序委託中獲得了不同的託管對象上下文,因此您不需要在此創建的對象上下文,因此可以刪除創建新上下文的代碼。您可能也想使用applicationDidBecomeActive中的應用程序委託的上下文,但您擁有的內容不一定是錯誤的。

  2. 您永遠不會保存更改。您需要在託管對象上下文上調用​​以將數據保存到持久性存儲文件。

  3. 爲了使用可轉換屬性,您保存的數據必須符合NSCoding(因爲Core Data不知道如何轉換任意類,而NSCoding是您如何告訴它該做什麼)。 NSArray確實如此,但數組中的所有內容也都符合同樣重要。如果你的自定義班級這樣做,你沒問題。如果沒有,您需要修復該問題以保存數組或找到另一種保存數據的方法。

  4. 我不相信你會得到一個可變的陣列,無論你做什麼。一旦你保存並獲取工作,你將得到一個不可變的數組作爲list屬性的值。所以如果你需要數組是可變的,你需要調用mutableCopy

+0

謝謝你的迴應。我已經提出了您的建議更改。現在我正在將我的對象符合NSCoding的過程中,因爲我得到一個無法識別的選擇器發送到實例錯誤。我會讓你知道這是如何解決的。並希望如果我遇到另一個問題,我們可以再討論一下。 – njyulan

+0

現在我已經實現了'NSCoding',看起來我能夠將數據保存在'appplicationDidEnterBackground'中。同樣在'applicationDidBecomeActive'中,我看到了正確數量的表格對象,但它們還沒有被轉換回來。這是我看到的輸出:「(entity:TableViewList; id:0xd000000000080002 ; data:)」I我不確定如何從結果數組中取消存檔數據。再次感謝。 – njyulan

+0

您正在提取'TableViewList'對象,而且看起來很正常。您需要獲取'list'屬性的值以重新獲取數組。 –