2011-03-24 11 views
55

私はカスタムオブジェクト、gestureRecognizerというサブクラスを持つUIImageViewサブクラスを持っています。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

+4

FYI:カスタムオブジェクトが 'NSCoding'に準拠し、' initWithCoder: 'と' encodeWithCoder: 'を実装している限り、それをアーカイブ時にルートオブジェクトとして使用できます。このコードのように 'NSMutableArray'に入れる必要はありません。 –

+2

FYI:NSKeyedArchiverとNSCodingの経緯、理由、理由についての詳しい情報が必要な場合は、http://nshipster.com/nscoding/をご覧ください。 – haxpor

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

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

Official References

アレイにカスタムオブジェクトタイプが含まれている場合、これが機能するには、タイプがNSCoding Protocolに準拠していることを確認する必要があります。

+1

感謝。したがって、配列に何があっても、保存されたときと同じように配列を返すはずです。配列の項目を取得して使用できるか? – jarryd

+0

私は間違っているかもしれませんが、私はこの単純なコードはカスタムオブジェクトでは動作しないと思っています。両方のメソッドが「いいえ」を返しています。 – Deco

+2

@Deco - カスタムオブジェクトタイプは、[NSCoding Protocol](https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSCoding_Protocol/Reference/Reference.html)に確認する必要があります。これはうまくいく。 – aroth

2

私の改善をコスタスのソリューションに共有したいと思います。もしsomeb彼らはそれを必要とします。

  1. クラス名を使用してオブジェクトを格納するテキストファイル名を生成できます。
  2. ビューコントローラのオブジェクトをviewWillDisAppearメソッドに保存し、viewDidLoadメソッドでそれらを復元するとよい解決策です。
  3. 重複するコードを避けるため、ファイル名は別の方法で生成する必要があります。
  4. オブジェクトを復元した後は、nilでないことを確認する必要があります。

- (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; 
} 
関連する問題