2011-03-26 24 views
1

我想在我的应用程序中有一个“永久的”NSDictionary,其中从应用程序启动开始,我可以访问元素,甚至在我杀死应用程序并重新启动它。
这个NSDictionary需要与应用程序紧密存储。一种方法是在每次启动应用程序时从Web Service数据创建NSDictionary,然后创建一个代表此NSDictionary的单例类,但我认为这不好。有一个NSDictionary,总是存储在一个应用程序

NSDictionary将近似地保存10-20个对象,其中键将是NSString或NSDate,并且该值将是NSArray。 NSArray最多可以有大约50个条目(平均可能只有5-25个条目)。

我打算使用这个NSDictionary作为计算的一部分,我在每次用户每隔50-100米移动一次时在代表locationManager:didUpdateToLocation:fromLocation:内进行计算。

建议我赞赏最好的方式,我可以做到这一点。

回答

5

只有在单例中使用NSDictionary不会让它在应用程序启动之间保持不变,您需要将它保存到磁盘,然后在应用程序启动时从磁盘读取它。

如果没有自定义对象中的NSDictionary(您创建的子类),或在NSArrays或非可言,你可以用这个方法来保存的NSDictionary是:

- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag

并打开字典从磁盘:

- (id)initWithContentsOfFile:(NSString *)path


但是如果你有自定义对象他们将需要符合NSCoding协议。你将不得不使用2层不同的方法来保存和打开它:

NSCoding是一个协议,所以在你的头,你需要添加它的接口线的末端:

@interface myClassName : NSObject <NSCoding> { 

(你应该补充的唯一事情是<NSCoding>

然后在你实现你的子类中,你需要添加下面的方法:

- (id)initWithCoder:(NSCoder *)decoder

和:

- (void)encodeWithCoder:(NSCoder *)encoder


当你想解除封存(/开)您的NSDictionary(其中某处包含这个类)的initWithCoder:方法被调用

encodeWithCoder:就是被称为当你的NSDictionary被归档(/保存)。 你不要自己调用这些。您需要在其中添加代码:

- (id)initWithCoder:(NSCoder *)decoder { 
    if ((self = [super initWithCoder:decoder])) { 
     aProperty = [[decoder decodeObjectForKey:@"aProperty"] retain]; 
     anotherProperty = [[decoder decodeObjectForKey:@"anotherProperty"] retain]; 
     aFloat = [decoder decodeFloatForKey:@"aFloat"]; 
    } 
    return self; 
} 

- (void)encodeWithCoder:(NSCoder *)encoder { 
    [super encodeWithCoder:encoder]; 
    [encoder encodeObject:aProperty forKey:@"aProperty"]; 
    [encoder encodeObject:anotherProperty forKey:@"anotherProperty"]; 
    [encoder encodeFloat:aFloat forKey:@"aFloat"]; 
} 

你需要对你想存储(通常所有属性,[和实例变量]你的类有)每个值类似的路线。请注意0​​系列与其他系列的不同之处。

只要每个属性都有自己的唯一键并且它们在两个方法之间匹配,键可以是任何您想要的字符串。我个人使用财产的名称,因为它更容易理解。


当你真正要保存的NSDictionary使用:

[NSKeyedArchiver archiveRootObject:myDictionary toFile:pathToMyDictionary]; 

,并打开词典:

NSDictionary *myDictionary = [NSKeyedUnarchiver unarchiveObjectWithFile:pathToMyDictionary]; 

(取决于你的代码,你可能需要retainmyDictionary


要获得路径到您的字典(用于保存和打开),这样做:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *pathToMyDictionary = [documentsDirectory stringByAppendingPathComponent:@"myDictionary.dat"]; 

希望帮助,如果您对此回答任何问题,只是评论:)

+0

什么是NSCoding协议? – aherlambang 2011-03-27 01:43:43

+0

NSCoding协议需要两种方法,一种是对类的属性进行编码,另一种是对属性进行解码。我会编辑我的答案。 – 2011-03-27 10:36:42

+0

一个问题..你有pathToMyDictionary ..例如,该路径应该在哪里? – aherlambang 2011-03-28 23:09:22

2

这听起来像你想NSUserDefaults。这存储应用程序首选项,但也可以使用其他位数据。它本质上是一个专用的单身字典,可以全面访问并自动保存。

+0

我不不知道...我认为NSUserDefaults似乎并不是这里的情况 – aherlambang 2011-03-27 01:32:13

+0

如果你保存应用程序的状态,那么它是用户默认的合法使用。您对您的需求的描述使其听起来像是默认设置所使用的内容。 – TechZen 2011-03-27 02:31:49

+0

如果我关闭应用程序,我想再次加载它,它会将NSDictionary存储在NSUserDefaults中吗? – aherlambang 2011-04-01 02:03:56

2

您可以轻松地使用[NSDictionary dictionaryWithContentsOfFile:foo]

如果适当的plist文件中生成一个NSDictionary,plist中可以包含在你的应用程序包,或者你可以抓住第一次启动从Web服务中的数据并写入给plist这个字典从未来加载。

+0

这就是我在字典中只需要只读数据的情况。 – 2011-03-26 22:23:00

+0

好吧,我还需要写这个NSDictionary – aherlambang 2011-03-27 01:44:51

+0

死容易:)当它需要更新时,再次写入文件。 – marramgrass 2011-03-27 09:21:53

相关问题