【问题标题】:Save large NSDictionary to disk iOS将大型 NSDictionary 保存到磁盘 iOS
【发布时间】:2013-09-09 11:25:04
【问题描述】:

我的应用程序旨在查看产品目录。从服务器 (xml) 接收到的所有数据都在 NSDictionary 中进行解析。所以 NSDictionary 包含大约 5000 个项目。使用 NSKeyedUnarchiver 读取字典需要 24 秒。这是不可接受的。

我不需要向前和向后兼容,因为应用更新后会重新下载目录并删除旧数据。

我的字典不是属性列表,所以 writeToFile 不起作用。

NSArchiever(NSUNarchiver) 将是解决问题的好方法,但它被 NSKeyedArchiver 取代。

有什么想法吗?也许我应该使用 CoreData,但我对此一无所知。

谢谢

【问题讨论】:

  • 为什么不直接使用保存在手机上的 SQlite 数据库?

标签: ios performance save nsdictionary disk


【解决方案1】:

您是否尝试将其保存为 JSON 格式的文件? NSJSONSerialization 将帮助您在文件数据和 NSDictionary 之间来回切换。它是在 iOS5 中添加的。

https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html

让我知道它是否对你来说足够好。

【讨论】:

  • 感谢您的建议。但是我的字典的键是 NSNumber 的实例(它是产品 ID),它不能转换为 JSON。
  • 您是否尝试过将键存储为这些数字的字符串表示形式?如果您真的不需要它们是数字,它可能会起作用。
  • 这就是我现在正在做的)但也许这是错误的做法。
  • 我的字典包含自定义类,所以我不能直接使用 NSJSONSerialization。但是找到了解决办法。
【解决方案2】:

我的解决方案是使用自定义序列化。最后,所有数据都以属性列表的形式呈现。我所有应该序列化的自定义类都支持协议 PropertyListCoder(如 NSCoder):

@protocol PropertyListCoder

- (id)encodeToPropertyListObject;
- (id)initWithPropertyListObject:(id)object;

@end

例如 Product 类的序列化:

@interface Product : NamedObject <NSCoding, PropertyListCoder> {
}

@property (nonatomic, readwrite) uint               mId;
@property (nonatomic, retain) NSString              *mDesc;
@property (nonatomic, retain) NSString              *mIcon;

@property (nonatomic, retain) NSString              *mCode;
@property (nonatomic, readwrite) uint               mSort;
@property (nonatomic, retain) NSMutableArray        *mArrOfText;

@property (nonatomic, readonly) NSMutableArray      *mProperties;
@property (nonatomic, retain) NSString              *mImage;
@property (nonatomic, readwrite) float              mPrice;
@property (nonatomic, readwrite) float              mDiscPrice;

@end

这里是协议的方法:

- (id)encodeToPropertyListObject {
id superPropList = [super encodeToPropertyListObject];
NSNumber* idNumber = [[NSNumber alloc] initWithInt:mId];
NSNumber* sortNumber = [[NSNumber alloc] initWithInt:mSort];
NSMutableArray* arrOfTextPropList = [[NSMutableArray alloc] init];
for (NSAttString* str in self.mArrOfText) {
    [arrOfTextPropList addObject:[str encodeToPropertyListObject]];
}
NSMutableArray* propPropList = [[NSMutableArray alloc] init];
for (Property* prop in self.mProperties) {
    [propPropList addObject:[prop encodeToPropertyListObject]];
}
NSNumber* priceNumber = [[NSNumber alloc] initWithInt:mPrice];
NSNumber* discPriceNumber = [[NSNumber alloc] initWithInt:mDiscPrice];

NSArray* res = [NSArray arrayWithObjects:superPropList, idNumber, [Utility notNilStringWithString:mDesc], [Utility notNilStringWithString:mIcon], [Utility notNilStringWithString:mCode], sortNumber, arrOfTextPropList, propPropList, [Utility notNilStringWithString:mImage], priceNumber, discPriceNumber, nil];

[idNumber release];
[sortNumber release];
[arrOfTextPropList release];
[propPropList release];
[priceNumber release];
[discPriceNumber release];

return res;
}

- (id)initWithPropertyListObject:(id)object {
NSArray* arr = (NSArray*)object;
self = [super initWithPropertyListObject:[arr objectAtIndex:0]];
if (self) {
    mId = [[arr objectAtIndex:1] intValue];
    mDesc = [[arr objectAtIndex:2] retain];
    mIcon = [[arr objectAtIndex:3] retain];
    mCode = [[arr objectAtIndex:4] retain];
    mSort = [[arr objectAtIndex:5] intValue];
    mArrOfText = [[NSMutableArray alloc] init];
    mProperties = [[NSMutableArray alloc] init];

    for (id subObj in (NSArray*)[arr objectAtIndex:6]) {
        NSAttString* str = [[NSAttString alloc] initWithPropertyListObject:subObj];
        [mArrOfText addObject:str];
        [str release];
    }
    for (id subObj in (NSArray*)[arr objectAtIndex:7]) {
        Property* prop = [[Property alloc] initWithPropertyListObject:subObj];
        [mProperties addObject:prop];
        [prop release];
    }
    mImage = [[arr objectAtIndex:8] retain];
    mPrice = [[arr objectAtIndex:9] floatValue];
    mDiscPrice = [[arr objectAtIndex:10] floatValue];
}
return self;
}

根对象可以是 NSDictionary 或 NSArray。然后对于读/写,我使用二进制格式的 NSPropertyListSerialization。 现在阅读字典需要 3.5 秒!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 2011-04-14
    • 1970-01-01
    相关资源
    最近更新 更多