在 NSUserDefaults 中存储自定义对象

发布于 2024-12-07 12:33:10 字数 1806 浏览 0 评论 0原文

我正在尝试在 NSUserDefaults 中保存一个对象,但我没有成功。场景是,我有一个 SyncObjct 类的对象syncObject。我在 SyncObject 类中实现了以下方法

- (NSMutableDictionary*)toDictionary;
+ (SyncObject*)getFromDictionary :(NSMutableDictionary*)dictionary;
- (id) initWithCoder: (NSCoder *)coder;
- (void) encodeWithCoder: (NSCoder *)coder;

,并且 SyncObject 类是 NSCoding 类。现在 SyncObject 类包含一个名为 jobsArray 的 NSMutableArray。该数组包含 JobsObject 类的对象。我也为此类实现了上述相同的方法,以使其编码兼容。在 SyncObject 类的 toDictionary 方法中,我通过编写以下行将此数组存储在字典中。

[dictionary setValue:jobsArray forKey:@"jobsArray"];

我通过编写以下行在 SyncOject 类的 getFromDictionary 方法中检索它。

    + (SyncObject*)getFromDictionary :(NSMutableDictionary*)dictionary 
{       
    NSLog(@"SyncObject:getFromDictionary");
    SyncObject *syncObject = [[SyncObject alloc] init];

    @try 
    {

        syncObject.noOfJobs = [[dictionary valueForKey:@"noOfJobs"] intValue];  
        syncObject.totalJobsPerformed = (TotalJobsPerformed*)[dictionary valueForKey:@"totalobsPerformed"];
        syncObject.jobsArray = [dictionary valueForKey:@"jobsArray"];

    }
    @catch (NSException * e) 
    {
        NSLog(@"EXCEPTION %@: %@", [e name], [e reason]);
    }
    @finally 
    {

    }

    return syncObject;
}

我还通过编写以下几行将syncObject存储在NSUserDefault中。

NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:syncObject];
[userStorage setObject:myEncodedObject forKey:SYNC_OBJECT];

我通过编写以下几行从 NSUserDefaults 检索对象

NSData *myEncodedObject = [userStorage objectForKey: SYNC_OBJECT];
    syncObject = (SyncObject*)[NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];

问题是我无法正确检索 jobsArray。返回一些无效的对象,并且应用程序在尝试访问它时崩溃。请问谁能告诉我这个问题的原因吗?

此致

I am trying to save an object in NSUserDefaults but i have not been successful in it. Scenario is that, I have an object syncObject of class SyncObjct. I have implemented following methods in SyncObject class

- (NSMutableDictionary*)toDictionary;
+ (SyncObject*)getFromDictionary :(NSMutableDictionary*)dictionary;
- (id) initWithCoder: (NSCoder *)coder;
- (void) encodeWithCoder: (NSCoder *)coder;

And also the SyncObject class is NSCoding class. Now SyncObject class contains an NSMutableArray with name jobsArray. This array contains objects of class JobsObject. I implemented same above methods for this class as well to make it coding compliant. In toDictionary method of SyncObject class, i am storing this array in dictionary by writing following line.

[dictionary setValue:jobsArray forKey:@"jobsArray"];

and I am retrieving it in getFromDictionary method of SyncOject class by writing following line.

    + (SyncObject*)getFromDictionary :(NSMutableDictionary*)dictionary 
{       
    NSLog(@"SyncObject:getFromDictionary");
    SyncObject *syncObject = [[SyncObject alloc] init];

    @try 
    {

        syncObject.noOfJobs = [[dictionary valueForKey:@"noOfJobs"] intValue];  
        syncObject.totalJobsPerformed = (TotalJobsPerformed*)[dictionary valueForKey:@"totalobsPerformed"];
        syncObject.jobsArray = [dictionary valueForKey:@"jobsArray"];

    }
    @catch (NSException * e) 
    {
        NSLog(@"EXCEPTION %@: %@", [e name], [e reason]);
    }
    @finally 
    {

    }

    return syncObject;
}

And also I am storing syncObject in NSUserDefault by writing following lines.

NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:syncObject];
[userStorage setObject:myEncodedObject forKey:SYNC_OBJECT];

I am retrieving the object from NSUserDefaults by writing following lines

NSData *myEncodedObject = [userStorage objectForKey: SYNC_OBJECT];
    syncObject = (SyncObject*)[NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];

Problem is that i am not able to retrieve jobsArray correctly. Some invalid object is returned and app crashes when trying to access it. Please can anyone tell me the reason of this problem?

Best Regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柒七 2024-12-14 12:33:10

我认为问题在于 NSUserDefaults 不支持存储自定义对象类型。

使用 -setObject 时的 Apple 文档: value 参数只能是属性列表对象:NSData、NSString、NSNumber、NSDate、NSArray 或 NSDictionary。对于 NSArray 和 NSDictionary 对象,它们的内容必须是属性列表对象。

您可以直接从 Apple 的 NSUserDefault 类参考手册

I believe the problem is that NSUserDefaults does not support storing of custom object types.

From Apple's documentation when using -setObject: The value parameter can be only property list objects: NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. For NSArray and NSDictionary objects, their contents must be property list objects.

You can review the remaining documentation directly from Apple's NSUserDefault Class Reference manual.

緦唸λ蓇 2024-12-14 12:33:10

自定义类.h

#import <Foundation/Foundation.h>

@interface Person : NSObject

@property(nonatomic, retain) NSArray *names;

@property(strong,nonatomic)NSString *name;


@end

自定义类.m

 #import "Person.h"

@implementation Person
@synthesize names;


- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.name forKey:@"name"];
}

- (id)initWithCoder:(NSCoder *)decoder {
    if((self = [super init])) {
        //decode properties, other class vars
        self.name = [decoder decodeObjectForKey:@"name"];

    }
    return self;
}


@end

创建 Person 类对象并从 NSUserDefaults 存储和检索存储的数据

存储的对象中存储和检索存储的数据:

#import "ViewController.h"
#import "Person.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextField *textBox;

@end

NSMutableArray *arr;

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (IBAction)saveButton:(id)sender {
    Person *person =[Person new];
    person.name = _textBox.text;

     arr = [[NSMutableArray alloc]init];
    [arr  addObject:person];

    NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:arr];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:encodedObject forKey:@"name"];
    [defaults synchronize];
}
- (IBAction)showButton:(id)sender {
    _label.text = @"";

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    NSData *storedEncodedObject = [defaults objectForKey:@"name"];
    NSArray *arrStoreObject = [NSKeyedUnarchiver unarchiveObjectWithData:storedEncodedObject];

    for (int i=0; i<arrStoreObject.count; i++)
    {
        Person *storedObject = [arrStoreObject objectAtIndex:i];

        _label.text = [NSString stringWithFormat:@"%@ %@",  _label.text , storedObject.name];

    }


}

@end

Custom class .h

#import <Foundation/Foundation.h>

@interface Person : NSObject

@property(nonatomic, retain) NSArray *names;

@property(strong,nonatomic)NSString *name;


@end

custom class .m

 #import "Person.h"

@implementation Person
@synthesize names;


- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.name forKey:@"name"];
}

- (id)initWithCoder:(NSCoder *)decoder {
    if((self = [super init])) {
        //decode properties, other class vars
        self.name = [decoder decodeObjectForKey:@"name"];

    }
    return self;
}


@end

To create Person class object and store and retrieve your stored data from NSUserDefaults

Stored your object :

#import "ViewController.h"
#import "Person.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextField *textBox;

@end

NSMutableArray *arr;

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (IBAction)saveButton:(id)sender {
    Person *person =[Person new];
    person.name = _textBox.text;

     arr = [[NSMutableArray alloc]init];
    [arr  addObject:person];

    NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:arr];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:encodedObject forKey:@"name"];
    [defaults synchronize];
}
- (IBAction)showButton:(id)sender {
    _label.text = @"";

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    NSData *storedEncodedObject = [defaults objectForKey:@"name"];
    NSArray *arrStoreObject = [NSKeyedUnarchiver unarchiveObjectWithData:storedEncodedObject];

    for (int i=0; i<arrStoreObject.count; i++)
    {
        Person *storedObject = [arrStoreObject objectAtIndex:i];

        _label.text = [NSString stringWithFormat:@"%@ %@",  _label.text , storedObject.name];

    }


}

@end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文