2011-03-24 116 views
55

我有一个自定义对象,UIImageView子类有几个gestureRecognizer对象。在iOS中保存/序列化自定义对象的正确方法

如果我有一些这些对象存储在NSMutableArray,这个对象的数组将如何保存到磁盘,以便它可以在用户再次运行应用程序时加载?我想从磁盘加载数组,并使用对象。

回答

116

我类似的东西,实现以下和完美的作品:

自定义对象(设置)应实现协议NSCoding:

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

- (id)initWithCoder:(NSCoder *)decoder { 
    if (self = [super init]) { 
     self.difficulty = [decoder decodeObjectForKey:@"difficulty"]; 
     self.language = [decoder decodeObjectForKey:@"language"]; 
     self.category = [decoder decodeObjectForKey:@"category"]; 
     self.playerType = [decoder decodeObjectForKey:@"playerType"]; 
    } 
    return self; 
} 

下面的代码将自定义对象到一个文件中( set.txt),然后将其恢复到阵列myArray:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:@"set.txt"]; 

NSMutableArray *myObject=[NSMutableArray array]; 
[myObject addObject:self.settings];  

[NSKeyedArchiver archiveRootObject:myObject toFile:appFile]; 

NSMutableArray* myArray = [NSKeyedUnarchiver unarchiveObjectWithFile:appFile]; 
+4

这应该有更多的选票。完整的解决方案,真的帮助我。谢谢! – ChrisC 2013-11-08 01:00:46

+4

仅供参考:只要您的自定义对象符合'NSCoding'并实现'initWithCoder:'和'encodeWithCoder:',就可以在归档时将其用作根对象。不需要像在这段代码中那样把它放在'NSMutableArray'中。 – 2014-06-17 16:31:13

+2

仅供参考:如果您想了解更多关于NSKeyedArchiver和NSCoding的时间和原因的更多信息,请参见http://nshipster.com/nscoding/。 – haxpor 2015-01-23 03:30:39

35
//store the array 
[NSKeyedArchiver archiveRootObject:myArray toFile:@"someFile"]; 

//load the array 
NSMutableArray* myArray = [NSKeyedUnarchiver unarchiveObjectWithFile:@"someFile"]; 

Official References

请注意,当数组包含自定义对象类型时,必须确保类型符合NSCoding Protocol,然后才能使用。

+1

感谢。所以这应该返回数组,就像它保存时一样,不管数组中有什么?数组项是可检索和可用的吗? – jarryd 2011-03-24 16:33:22

+0

我可能只是做错了,但我不认为代码这个简单适用于自定义对象,两种方法都返回'否'。 – Deco 2013-04-12 14:40:25

+2

@Deco - 自定义对象类型必须确认[NSCoding Protocol](https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSCoding_Protocol/Reference/Reference.html)这工作。 – aroth 2013-04-15 07:12:41

2

我想分享我对Kostas解决方案的改进,如果someb ody需要他们。

  1. 类名可用于生成文本文件名来存储对象。
  2. 这是一个很好的解决方案,可以在viewWillDisappear方法中保存视图控制器的对象,并在viewDidLoad方法中恢复它们。
  3. 文件名应该在单独的方法中生成以避免重复的代码。
  4. 恢复对象后,应该检查为不是零。

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // Restoring form object from the file 
    NSString *formFilePath = [self formFilePath]; 
    RRCreateResumeForm *form = [NSKeyedUnarchiver unarchiveObjectWithFile:formFilePath]; 
    if (form != nil) { 
    self.formController.form = form; 
    } 
} 


- (void)viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 

    // Saving the form object to the file 
    NSString *formFilePath = [self formFilePath]; 
    [NSKeyedArchiver archiveRootObject:self.formController.form toFile:formFilePath]; 
} 


// Returns a file path to the file with stored form data for form controller 
- (NSString *)formFilePath 
{ 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *formClassName = NSStringFromClass([self.formController.form class]); 
    NSString *formFileName = [NSString stringWithFormat:@"%@.txt", formClassName]; 
    NSString *formFilePath = [documentsDirectory stringByAppendingPathComponent:formFileName]; 

    return formFilePath; 
}