将自定义对象存储在 NSUserDefaults 中的 NSMutableArray 中 [英] Storing custom objects in an NSMutableArray in NSUserDefaults

查看:26
本文介绍了将自定义对象存储在 NSUserDefaults 中的 NSMutableArray 中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近一直在尝试将我的 iPhone 应用程序的搜索结果存储在 NSUserDefaults 集合中.我也使用它来成功保存用户注册信息,但由于某种原因,尝试存储我的自定义位置类的 NSMutableArray 总是返回空.

I've recently been trying to store the search results of my iPhone app in the NSUserDefaults collection. I also use this to save user registration info successfully, but for some reason trying to store my NSMutableArray of custom Location classes always comes back empty.

在这篇文章中,我尝试将 NSMutableArray 转换为 NSData 元素,但得到了相同的结果(可以在 iPhone 上使用 NSUserDefaults 保存整数数组吗?)

I tried converting the NSMutableArray to a NSData element as of this post but I get the same result (Possible to save an integer array using NSUserDefaults on iPhone?)

我尝试过的代码示例是:

The code samples I have tried are:

保存:

[prefs setObject:results forKey:@"lastResults"];
[prefs synchronize];

NSData *data = [NSData dataWithBytes:&results length:sizeof(results)];
[prefs setObject:data forKey:@"lastResults"];

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:results];
[prefs setObject:data forKey:@"lastResults"];

加载:

lastResults = (NSMutableArray *)[prefs objectForKey:@"lastResults"];

NSData *data = [prefs objectForKey:@"lastResults"];
memcpy(&lastResults, data.bytes, data.length);  

NSData *data = [prefs objectForKey:@"lastResults"];
lastResults = [NSKeyedUnarchiver unarchiveObjectWithData:data];

在遵循以下建议后,我还在我的对象中实现了 NSCoder(忽略 NSString 的临时过度使用):

After following advice below I have also implemented NSCoder in my object (ignore the overuse of NSString its temporary):

#import "Location.h"


@implementation Location

@synthesize locationId;
@synthesize companyName;
@synthesize addressLine1;
@synthesize addressLine2;
@synthesize city;
@synthesize postcode;
@synthesize telephoneNumber;
@synthesize description;
@synthesize rating;
@synthesize priceGuide;
@synthesize latitude;
@synthesize longitude;
@synthesize userLatitude;
@synthesize userLongitude;
@synthesize searchType;
@synthesize searchId;
@synthesize distance;
@synthesize applicationProviderId;
@synthesize contentProviderId;

- (id) initWithCoder: (NSCoder *)coder
{
    if (self = [super init])
    {
        self.locationId = [coder decodeObjectForKey:@"locationId"];
        self.companyName = [coder decodeObjectForKey:@"companyName"];
        self.addressLine1 = [coder decodeObjectForKey:@"addressLine1"];
        self.addressLine2 = [coder decodeObjectForKey:@"addressLine2"];
        self.city = [coder decodeObjectForKey:@"city"];
        self.postcode = [coder decodeObjectForKey:@"postcode"];
        self.telephoneNumber = [coder decodeObjectForKey:@"telephoneNumber"];
        self.description = [coder decodeObjectForKey:@"description"];
        self.rating = [coder decodeObjectForKey:@"rating"];
        self.priceGuide = [coder decodeObjectForKey:@"priceGuide"];
        self.latitude = [coder decodeObjectForKey:@"latitude"];
        self.longitude = [coder decodeObjectForKey:@"longitude"];
        self.userLatitude = [coder decodeObjectForKey:@"userLatitude"];
        self.userLongitude = [coder decodeObjectForKey:@"userLongitude"];
        self.searchType = [coder decodeObjectForKey:@"searchType"];
        self.searchId = [coder decodeObjectForKey:@"searchId"];
        self.distance = [coder decodeObjectForKey:@"distance"];
        self.applicationProviderId = [coder decodeObjectForKey:@"applicationProviderId"];
        self.contentProviderId = [coder decodeObjectForKey:@"contentProviderId"];
    }
}

- (void) encodeWithCoder: (NSCoder *)coder
{
    [coder encodeObject:locationId forKey:@"locationId"];
    [coder encodeObject:companyName forKey:@"companyName"];
    [coder encodeObject:addressLine1 forKey:@"addressLine1"];
    [coder encodeObject:addressLine2 forKey:@"addressLine2"];
    [coder encodeObject:city forKey:@"city"];
    [coder encodeObject:postcode forKey:@"postcode"];
    [coder encodeObject:telephoneNumber forKey:@"telephoneNumber"];
    [coder encodeObject:description forKey:@"description"];
    [coder encodeObject:rating forKey:@"rating"];
    [coder encodeObject:priceGuide forKey:@"priceGuide"];
    [coder encodeObject:latitude forKey:@"latitude"];
    [coder encodeObject:longitude forKey:@"longitude"];
    [coder encodeObject:userLatitude forKey:@"userLatitude"];
    [coder encodeObject:userLongitude forKey:@"userLongitude"];
    [coder encodeObject:searchType forKey:@"searchType"];
    [coder encodeObject:searchId forKey:@"searchId"];
    [coder encodeObject:distance forKey:@"distance"];
    [coder encodeObject:applicationProviderId forKey:@"applicationProviderId"];
    [coder encodeObject:contentProviderId forKey:@"contentProviderId"];

}

推荐答案

为了在数组中加载自定义对象,这是我用来抓取数组的方法:

For loading custom objects in an array, this is what I've used to grab the array:

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"savedArray"];
if (dataRepresentingSavedArray != nil)
{
    NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
    if (oldSavedArray != nil)
        objectArray = [[NSMutableArray alloc] initWithArray:oldSavedArray];
    else
        objectArray = [[NSMutableArray alloc] init];
}

您应该检查从用户默认值返回的数据是否不是 nil,因为我认为从 nil 取消归档会导致崩溃.

You should check that the data returned from the user defaults is not nil, because I believe unarchiving from nil causes a crash.

归档很简单,使用以下代码:

Archiving is simple, using the following code:

[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:objectArray] forKey:@"savedArray"];

正如 f3lix 所指出的,您需要使您的自定义对象符合 NSCoding 协议.添加如下方法应该可以解决问题:

As f3lix pointed out, you need to make your custom object comply to the NSCoding protocol. Adding methods like the following should do the trick:

- (void)encodeWithCoder:(NSCoder *)coder;
{
    [coder encodeObject:label forKey:@"label"];
    [coder encodeInteger:numberID forKey:@"numberID"];
}

- (id)initWithCoder:(NSCoder *)coder;
{
    self = [super init];
    if (self != nil)
    {
        label = [[coder decodeObjectForKey:@"label"] retain];
        numberID = [[coder decodeIntegerForKey:@"numberID"] retain];
    }   
    return self;
}

这篇关于将自定义对象存储在 NSUserDefaults 中的 NSMutableArray 中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆