在Core Data中存储和获取NSMutableArray

时间:2015-08-27 23:00:07

标签: ios objective-c iphone core-data nsmutablearray

我希望在我的应用程序终止/进入后台时将NSMutableArray保存到Core-Data,并且当我的应用程序启动/变为活动状态时,我想加载NSMutableArray

我还没有对Core-Data有很好的理解。这是我第一次使用它。我查看过一堆视频,教程,之前的Stackoverflow问题和Apple的文档。我认为我想要做的事情属于Apple的Core-Data文档中的非标准持久属性章节。

我已经建立了一个名为TableViewList的实体,并且我给它一个名为List of type of transformable的属性。

这是我的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

1 个答案:

答案 0 :(得分:3)

好的,这里有几件事要提到:

  1. applicationDidEnterBackground中,方法的前半部分配置了一个您从未使用过的新托管对象上下文。由于您从应用程序委托中获取了不同的托管对象上下文,因此您不会在此处创建该托管对象上下文,因此可以删除创建新上下文的代码。你可能也想在applicationDidBecomeActive中使用app delegate的上下文,虽然你所拥有的并不一定是错的。

  2. 您永远不会保存更改。您需要在托管对象上下文中调用save:以将数据保存到持久性存储文件。

  3. 为了使用可转换属性,您保存的数据必须符合NSCoding(因为Core Data不知道如何转换任意类,NSCoding是如何你告诉它该怎么做)。 NSArray可以,但同样重要的是数组中的所有内容也符合要求。如果您的自定义类执行此操作,那么您就可以了。如果没有,您需要修复此问题以保存数组或找到另一种保存数据的方法。

  4. 无论你做什么,我都不相信你会得到一个可变的阵列。保存并获取工作后,您将获得一个不可变数组作为list属性的值。因此,如果您需要数组是可变的,则需要调用mutableCopy