简体   繁体   English

在核心数据中存储和获取NSMutableArray

[英]Store and fetch NSMutableArray in Core Data

I would like to save the NSMutableArray to Core-Data when my application terminates/goes into background and I would like to load the NSMutableArray when my application launches/becomes active. 当我的应用程序终止/进入后台时,我想将NSMutableArray保存到Core-Data ,并且当我的应用程序启动/变得活动时,我想加载NSMutableArray

I don't have a very good understanding of Core-Data yet. 我对Core-Data还没有很好的了解。 This is my first time working with it. 这是我第一次使用它。 I've looked at a bunch of videos, tutorials, previous Stackoverflow questions and Apple's documentation. 我看了很多视频,教程,以前的Stackoverflow问题和Apple的文档。 I think what I am trying to do falls under the Non-Standard Persistent Attributes chapter in Apple's Core-Data documentation. 我认为我要尝试做的事属于Apple Core-Data文档中的“非标准持久性属性”一章。

I have set up an Entity called TableViewList and I have given it an attribute called List of type transformable. 我已经建立了一个名为TableViewList的实体,并给了它一个名为List of可转换类型的属性。

Here is my AppDelegate.h and .m code. 这是我的AppDelegate.h和.m代码。 All advice would be wonderful. 所有建议将是美好的。

AppDelegate.h 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 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);
}

The result array returns an empty array. 结果数组返回一个空数组。 I don't think I'm saving and fetching the array correctly. 我认为我没有正确保存和获取数组。 Thanks in advance for your help! 在此先感谢您的帮助!

I used this link to implement NSCoding in my object. 我使用此链接在对象中实现NSCoding

OK there are several things to mention here: 好,这里有几件事要提到:

  1. In applicationDidEnterBackground , the first half of the method configures a new managed object context that you never use. applicationDidEnterBackground ,方法的前半部分配置您从未使用过的新托管对象上下文。 Since you then get a different managed object context from the app delegate, you don't the one you create here, so the code that creates a new context can be deleted. 由于您从应用程序委托那里获得了不同的托管对象上下文,因此不必在此处创建该对象,因此可以删除创建新上下文的代码。 You probably also want to use the app delegate's context in applicationDidBecomeActive , though what you have isn't necessarily wrong. 您可能还想在applicationDidBecomeActive使用应用程序委托的上下文,尽管您所拥有的不一定是错误的。

  2. You don't ever save changes. 您永远不会保存更改。 You need to call save: on the managed object context to save data to the persistent store file. 您需要在托管对象上下文上调用save:将数据保存到持久性存储文件中。

  3. In order to use a transformable property, the data you're saving must conform to NSCoding (because Core Data doesn't know how to transform arbitrary classes, and NSCoding is how you tell it what to do). 为了使用可转换的属性,您保存的数据必须符合NSCoding (因为Core Data不知道如何转换任意类,而NSCoding就是您告诉它要做什么)。 NSArray does, but it's also important that everything in the array also conforms. NSArray确实可以,但是数组中的所有内容也必须保持一致也很重要。 If your custom class does that, you're OK. 如果您的自定义类做到了,那就可以了。 If not, you'll need to fix that to save the array or find a different way to save your data. 如果不是,则需要修复该问题以保存阵列或找到其他方法来保存数据。

  4. I don't believe that you're going to get a mutable array back, no matter what you do. 无论您做什么,我都不相信您会得到可变的数组。 Once you get saving and fetching working, you'll get an immutable array as the value of the list property. 保存并获取工作后,您将获得一个不可变的数组作为list属性的值。 So you'll need to call mutableCopy if you need the array to be mutable. 因此,如果需要使数组可变,则需要调用mutableCopy

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM