2012-02-18 12 views
5

私はそうのようなplistのリストファイルにカスタムオブジェクトの配列を保存しています:に成功ObjectiveCでWRITETOFILEで書かれたファイルをロードするためにarrayWithContentsOfFileを使用する方法/ XCodeの

を:のようなファイルが作成されます

+(void) arrayToPlist: (NSArray*) plant_types{ 
    NSMutableArray* dictionary_array = [NSMutableArray arrayWithCapacity: plant_types.count]; 

    for(int i = 0; i<plant_types.count; i++){ 
     PlantType* pt = [plant_types objectAtIndex: i]; 
     [dictionary_array addObject: [pt toDict]]; 
    } 

    NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
    NSString* filePath = [rootPath stringByAppendingPathComponent:@"PlantTypes.plist"]; 
    NSLog(@"Writing plist to: %@", filePath); 

    [dictionary_array writeToFile: filePath atomically: YES]; 
} 

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 
<plist version="1.0"> 
<array> 
    <dict> 
     <key>name</key> 
     <string>Autumn Olive</string> 
     <key>radius</key> 
     <real>10</real> 
    </dict> 
    <dict> 
     <key>name</key> 
     <string>Dwarf Cherry</string> 
     <key>radius</key> 
     <real>5</real> 
    </dict> 
    <dict> 
     <key>name</key> 
     <string>Bamboo</string> 
     <key>radius</key> 
     <real>2</real> 
    </dict> 
    <dict> 
     <key>name</key> 
     <string>Pomegranate</string> 
     <key>radius</key> 
     <real>6</real> 
    </dict> 
    <dict> 
     <key>name</key> 
     <string>Lupin</string> 
     <key>radius</key> 
     <real>0.60000002384185791</real> 
    </dict> 
</array> 
</plist> 

そして、このようにそれらをロードする:

+(NSMutableArray*) arrayFromPlist{ 
    NSLog(@"Loading array of plant types from plist."); 

    NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
    NSString* filePath = [rootPath stringByAppendingPathComponent:@"PlantTypes.plist"]; 
    NSFileManager* fileManager = [NSFileManager defaultManager]; 

    if([fileManager fileExistsAtPath:filePath]){ 
     NSLog(@"Plist file exists at expected location."); 
     NSMutableArray* plant_dicts = [NSMutableArray arrayWithContentsOfFile:filePath]; 
     NSLog(@"Loaded array with contents of file, got %d plant types.", plant_dicts.count); 
     NSMutableArray* plant_types = [NSMutableArray arrayWithCapacity: plant_dicts.count]; 
     for(int i = 0; i< plant_dicts.count; i++){ 
      NSMutableDictionary* dict = [plant_dicts objectAtIndex: i]; 
      [plant_types addObject: [PlantType fromDict: dict]]; 
     } 
     return plant_types; 
    } 
    NSLog(@"Plant Type plist file not found."); 
    return NULL; 
} 

クラッシュナッシングが、毎回Iサイズ0のNSMutableArrayを返します(そして、そのロギングステートメントはplant_dictsがサイズゼロであることを確認します)。

私は間違っていますか?私がarrayWithContentsOfFile:と表示している同様の問題は、plistを手作業で、またはエディタで作成している人です。コード自体から作成すると、これらの問題は発生しないでしょう...

編集:I私がもはやサイズゼロの結果を得ていないことを確認しました(これは奇妙です、元の投稿からそのセクションにコードの変更はありません)。しかし、私はまだ物事を正しく読み込んでいません。ここに私のfromDictとtoDictメソッドがあります。

文字列「シェイプ」が正しく読み込まれていないように見えることが問題です。少なくとも、私がshape == @ "Circle"を尋ねると、NSLogステートメントではっきりとしても、それはできません。私はコード内のどこでも同じ比較をしています(オブジェクトをレンダリングする方法を調べるとき)、それはうまくいきます(つまり、Javaにあるような奇妙な==対等なものはないと仮定します)。

ダブル編集:[shape isEqualToString:@ "Circle"]がありません。なぜ私が混乱する前にそれを使用する必要はありませんでしたか?あなたのplistで

+0

うん、。 ==は、文字列の内容ではなく、ポインタが同じであることを確認するだけです。コンパイラは、同じ文字列の2つのインスタンスに対して同じポインタを使用できることを知っているので、==はレンダリングコードで動作していました。しかし、それらの文字列の1つがplistから出てきたら、別のポインタになります。 – davehayden

答えて

4

、このコードは、私は問題があなたのPlantType実装から来ると思います

+(NSMutableArray*) arrayFromPlist{ 
    NSLog(@"Loading array of plant types from plist."); 

    NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
    NSString* filePath = [rootPath stringByAppendingPathComponent:@"PlantTypes.plist"]; 
    NSFileManager* fileManager = [NSFileManager defaultManager]; 

    if([fileManager fileExistsAtPath:filePath]){ 
     NSLog(@"Plist file exists at expected location."); 
     NSMutableArray* plant_dicts = [NSMutableArray arrayWithContentsOfFile:filePath]; 
     NSLog(@"Loaded array with contents of file, got %d plant types.", plant_dicts.count); 
     NSMutableArray* plant_types = [NSMutableArray arrayWithCapacity: plant_dicts.count]; 
     for(int i = 0; i< plant_dicts.count; i++){ 
      NSMutableDictionary* dict = [plant_dicts objectAtIndex: i]; 
      [plant_types addObject: dict]; 
     } 
     return plant_types; 
    } 
    NSLog(@"Plant Type plist file not found."); 
    return NULL; 
} 

結果

2012-02-22 16:24:43.697 Test[5574:10103] Loading array of plant types from plist. 
2012-02-22 16:24:43.698 Test[5574:10103] Plist file exists at expected location. 
2012-02-22 16:24:43.699 Test[5574:10103] Loaded array with contents of file, got 5 plant types. 
2012-02-22 16:24:43.700 Test[5574:10103](
     { 
     name = "Autumn Olive"; 
     radius = 10; 
    }, 
     { 
     name = "Dwarf Cherry"; 
     radius = 5; 
    }, 
     { 
     name = Bamboo; 
     radius = 2; 
    }, 
     { 
     name = Pomegranate; 
     radius = 6; 
    }, 
     { 
     name = Lupin; 
     radius = "0.6000000238418579"; 
    } 
) 

正しい結果を返します。

NSMutableDictionary* dict = [plant_dicts objectAtIndex: i]; 

は可変辞書を返しませんが、不変1:あなたはあなたのコード(toDictとfromDict方法)

0

このラインを投稿することができます。あなたはそれを可変にしたい場合は

、あなたはこれらの線に沿って何かをする必要があります:あなたは、Javaの場合と同様の理由で、isEqualToStringをしたい文字列を

MutableDictionary* dict = [NSMutableDictionary dictionaryWithDictionary: [plant_dicts objectAtIndex: i]]; 
関連する問題