Iphone 使用指向NSData的指针序列化结构
我需要在Objective-C Trie实现(在github上)中添加一些归档功能,但我对C及其数据结构的使用经验很少Iphone 使用指向NSData的指针序列化结构,iphone,c,objective-c,cocoa,serialization,Iphone,C,Objective C,Cocoa,Serialization,我需要在Objective-C Trie实现(在github上)中添加一些归档功能,但我对C及其数据结构的使用经验很少 struct trieNode { NSUInteger key; NSUInteger count, size; id object; __strong struct trieNode ** children; __strong struct trieNode * parent; }; @interface NDTrie (P
struct trieNode
{
NSUInteger key;
NSUInteger count,
size;
id object;
__strong struct trieNode ** children;
__strong struct trieNode * parent;
};
@interface NDTrie (Private)
- (struct trieNode*)root;
@end
我需要的是从根目录创建一个具有树结构的NSData
,或者以其他方式对整个树进行序列化/反序列化(符合NSCoding
?),但我不知道如何使用NSData
和包含指针的C结构
反序列化结果对象的性能至关重要,因为这是一个iPhone项目,每次应用程序启动时,我都需要在后台加载它
实现这一目标的最佳方式是什么
谢谢 你应该先尝试简单的方法:
// serializing:
[myTrie writeToFile:myPath atomically:NO];
// deserializing
NDTrie* myTrie = [NDTrie trieWithContentsOfFile:myPath];
如果这真的不够快,您可以研究手动序列化底层结构
编辑:
您明确表示,数据量需要优化的实现
我建议重写Trinode结构和访问方法,使用索引而不是父字段
和子字段
的指针。索引将指向一个三节点结构的大型C数组,所有节点都从该数组中分配
此C数组可以保存在包装
NDTrie
对象中的NSData对象中。序列化和反序列化只意味着保存/加载NSData对象(endianess问题除外)。将trie节点结构重新实现为目标C类。e、 g
@interface TrieNode
{
NSUinteger key;
NSUInteger count;
//NSUInteger size; // not needed if you use an NSArray for the children.
id object;
NSArray* children;
TrieNode* parent;
}
// methods
@end
然后,您可以使用标准的Objective-C机制来归档和取消归档这些对象
如果在实现上述内容并分析代码之后,发现性能有问题,可以开始优化。例如,通过使用C结构指针访问IVAR,例如
aTrieNode->parent;
或者用C数组替换NSArray等。假设您需要使用直C,因为这就是设置的方式,您需要做的实际上非常简单 只需编写一个C函数,将树写入磁盘,并对排序进行一些假设(例如,您将其写入我们的深度优先,从左到右)。对于任何Objective-C对象,将其编码为NSData,并将其大小和字节作为流的一部分写出 当您读回数据时,只需根据您的排序假设重构树,并设置指向子级的指针。根据需要取消归档任何嵌入的Objective-C对象 您可能可以通过NSCoder以某种方式实现这一点,但在NSCoder之外进行树重建可能会更容易,因为您可以在树上递归传递任何您喜欢的参数,这对于NSCoding来说并不容易 我确实有一些(桌面操作系统X)代码可以做类似的事情,没有嵌入的对象,但是它非常复杂,我不能发布它
该代码的一个优化是将数据读入内部缓冲区,以MB为单位(而不是每次读取少量字节,针对每个结构),然后从该缓冲区读取数据,尽管我不确定该数据是否经过基准测试,而且在任何情况下,它可能会或可能不会在iPhone上产生显著差异。看起来也有类似的写作优化,据我所知,这更有可能是一场胜利(iPhone写东西很贵,或者我听说过).我认为您应该实现NSCoding协议:在
initWithCoder:
中创建一个包含所有子项的NSArray,并在encodeWithCoder:
中重新定位这样的结构数组
通过这种方式,您将能够在项目的其余部分使用struct的原始数组。问题是我的数据集非常大,目前我无法使它同时适合设备内存上的临时NSArray和实际trie数据结构,而且创建这两种结构的速度太慢。这就是为什么我在寻找一种方法来跳过这个数组的重新创建并序列化实际的trie模型。问题是我必须重写整个现有的实现来使用类而不是结构-这就是为什么我在寻找一种方法来序列化现有的结构,它的实现速度应该要快得多。在我看来,它没有太多的意义。它只是一个源文件,如果使用类,您可能会发现事情简化了。我自己也可以试试。。。