2

私は次のような構造のplistを使用しています:plist、array、dictキー文字列キー文字列/ dict、dictキー文字列キー文字列/ dict、/ array、/plist。

次のコードで必要なのは、現在の辞書の「Done」文字列の値を「Yes」に設定することです。

しかし今では、コードは辞書の配列全体を現在の辞書の文字列に置き換えます(ただし、「Done」キーの値は「Yes」になります)。

私が欲しいものの正しいコードは何でしょうか?

DetailViewController.m:

-(IBAction)favoriteButtonPressed:(id)sender
{

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"Object.plist"];


[[detailsDataSource objectAtIndex: detailIndex] setValue:@"Yes" forKey:@"Done"];
[[detailsDataSource objectAtIndex: detailIndex] writeToFile:path atomically:YES];
}

detailsDataSourceとdetailIndexは、それが重要な場合、TableViewController.mセグエから受信されます。

TableViewController.mセグエ部分:

    detailViewController.detailsDataSource = [[NSArray alloc]initWithArray:objectsArray];
    detailViewController.detailIndex = selectedRowIndex.row;

DetailViewController viewDidLoad

if ([[[detailsDataSource objectAtIndex: detailIndex] valueForKey:@"Favorite"] isEqual:@"Yes"])  {

    [favoriteButton setImage:[UIImage imageNamed:@"favoritedItem.png"] forState:UIControlStateSelected | UIControlStateHighlighted];
 }


districtLabel.text = [[detailsDataSource objectAtIndex: detailIndex] valueForKey:@"District"];

detailsDataSource配列はdetailViewControllerでこのように使用されるため、配列から辞書に変更することはできません。その場合は、変更可能なコピーを作成する必要があります。

4

2 に答える 2

2

setValue:forKey可変辞書を変更するためのものではありません。を使用する必要がありますsetObject:forKey。つまり、これ:

[[detailsDataSource objectAtIndex: detailIndex] setValue:@"Yes" forKey:@"Done"];

する必要があります:

[[detailsDataSource objectAtIndex: detailIndex] setObject:@"Yes" forKey:@"Done"];

それでも問題が解決しない場合は、辞書と配列の両方が変更可能であることを確認してください。

-(IBAction)favoriteButtonPressed:(id)sender {

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"Object.plist"];

    NSMutableDictionary *mutDict = [NSMutableDictionary dictionaryWithDictionary:[detailsDataSource objectAtIndex:detailIndex]];
    [mutDict setObject:@"Yes" forKey:@"Done"];

    NSMutableArray *tmpMutArr = [NSMutableArray arrayWithArray:detailsDataSource];
    [tmpMutArr replaceObjectAtIndex:detailIndex withObject:[NSDictionary dictionaryWithDictionary:mutDict]];  // make dict immutable before replacing.  Casting it ( (NSDictionary *)mutDict ) works too.

    [detailsDataSource release], detailsDataSource = nil;
    detailsDataSource = [[NSArray alloc] initWithArray:tmpMutArr];

    [detailsDataSource writeToFile:path atomically:YES];
}

また、の代わりに、 :@"Yes"を使用できます。 通常は、を使用するよりも適切な形式になります。[NSNumber numberWithBool:YES]
[mutDict setObject:[NSNumber numberWithBool:YES] forKey:@"Done"];
@"Yes"

と:

districtLabel.text = [[detailsDataSource objectAtIndex: detailIndex] valueForKey:@"Yes"];

する必要があります:

districtLabel.text = [[detailsDataSource objectAtIndex: detailIndex] objectForKey:@"Yes"];

また、次の場合にメモリリークが発生する可能性があることにも注意してください。

detailViewController.detailsDataSource = [[NSArray alloc] initWithArray:objectsArray];

保持するプロパティセッターを使用する場合は、必ず自動リリースしてください。

于 2012-08-12T16:15:30.257 に答える
2
[[detailsDataSource objectAtIndex: detailIndex] setObject:@"Yes" forKey:@"Done"];
于 2012-08-12T16:17:50.173 に答える