为啥 plist 中的项目会被覆盖?

Posted

技术标签:

【中文标题】为啥 plist 中的项目会被覆盖?【英文标题】:Why does item in plist gets overwritten?为什么 plist 中的项目会被覆盖? 【发布时间】:2011-08-22 09:27:53 【问题描述】:

我正在尝试向我的 plist 添加一个新项目。但是,每次我按保存时它都会被覆盖:

-(IBAction)save:(id)sender 

 appDelegate = (JobTestAppDelegate*)[[UIApplication sharedApplication]delegate]; 

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

 NSMutableDictionary* newNote = [[NSMutableDictionary alloc] init];  

 NSMutableDictionary *set = [NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"", @"", nil] forKeys:[NSArray arrayWithObjects:@"Work Name", @"Work ID", nil]];

NSArray *work = [NSArray arrayWithObjects:set, nil];

int row = 0;
newNote = [appDelegate.job objectAtIndex:row];
[newNote setValue:work forKey:@"Work"];         

[appDelegate.job writeToFile:fileName atomically:TRUE];

[newNote release];  

[self dismissModalViewControllerAnimated:YES];
 

我不知道代码的哪一部分是错误的。这几天我一直在努力解决这个问题。

编辑: appDelegate.job - 我的主应用程序委托类中的一个可变数组,用于创建 plist:

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

job = [[NSMutableArray alloc] initWithContentsOfFile:fileName];


[job writeToFile:fileName atomically:YES];

EDIT2:

我需要将用户输入(NSArray*work)存储到工作数组中

根(数组)

        Item 0 (Dict)
                      Name (String)
                      Work (Array)
                                       Item 0 (Dict)
                                                    Work Name (String)
                                                    Work ID (String)
                                       Item 1 (Dict)
                                                    Work Name (String)
                                                    Work ID (String)
        Item 1 (Dict)
                      Name (String)
                      Analysis (Array)
                                       Item 0 (Dict)
                                                    Work Name (String)
                                                    Work ID (String)
                                       Item 1 (Dict)
                                                    Work Name (String)
                                                    Work ID (String)

编辑3: NSMutableDictionary* newNote = [[NSMutableDictionary alloc] init];

 NSMutableDictionary *set = [NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"", @"", nil] forKeys:[NSArray arrayWithObjects:@"Work Name", @"Work ID", nil]];

NSArray *work = [NSArray arrayWithObjects:set, nil];

int row = item;
newNote = [appDelegate.job objectAtIndex:row];
[newNote setValue:work forKey:@"Work"];         

//i think this is the line which i am having problem with.
//without this line my data in the plist gets overwritten, 
//with this code it copies the who item and create a new item into my root array
[appDelegate.job addObject:newNote];

[appDelegate.job writeToFile:fileName atomically:TRUE];

[newNote release];  

提前致谢, 莉安娜

【问题讨论】:

什么是 appDelegate.job?你能发布一些与它的操作相关的代码吗? 感谢您的及时回复(:我已经编辑了我的问题并发布了 appDelegate.job 的代码。您知道我的代码中缺少什么或错误吗?谢谢(: 【参考方案1】:

您正在用新项目覆盖作业索引为零的任何内容。您也在此处分配内存:

NSMutableDictionary* newNote = [[NSMutableDictionary alloc] init]; 

然后在这里给这个变量重新赋值:

newNote = [appDelegate.job objectAtIndex:row];

如果您尝试添加新项目,您应该执行以下操作:

NSMutableDictionary* newNote = [[NSMutableDictionary alloc] init];
[newNote setValue:work forKey:@"Work"];
[appDelegate.job addObject:newNote];
[appDelegate.job writeToFile:fileName atomically:TRUE];

然后,您将向作业数组添加一个新字典,并写出整个数组。

编辑:从您的 cmets 看来,newNote 应该是一个字典,其中包含一个名称和一个数组。因此,您需要向现有数组添加一个新对象 - 您当前正在将单个项目数组设置为该字典的“工作”键。

你需要这样的东西:

NSMutableDictionary* newNote = [appDelegate.job objectAtIndex:0];
NSArray *oldWork = [newNote objectForKey:@"Work"];
NSArray *newWork = [oldWork arrayByAddingObject:set];
[newNote setObject:newWork forKey:@"Work"];

【讨论】:

感谢您的回复(:上面的代码会将我的代码保存为我的根数组中的一个项目,但是我想将它存储到我的工作数组(这是一个子/子键)中显示在 plist上面。如何编辑我的代码以使其将新项目保存到工作数组中而不是覆盖它?非常感谢(: 谢谢(:但代码确实有效。我知道我的代码的哪一部分发生了错误。我已经编辑了它。你能帮我看看吗。谢谢 您仍在用一个全新的数组覆盖键 @"work" 的对象。在我上面的回答中,我采用当前数组,然后将新的“set”字典添加到其中,然后将其重新分配给键 @“work”。

以上是关于为啥 plist 中的项目会被覆盖?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 a:hover 在 CSS 中会被覆盖?

关于django url 为啥会被覆盖?

为啥使用 DT_MODIFYSTRING 选项将副本传递给 DrawText 函数时,原始 CString 会被覆盖?

通过 info.plist 中的 CFBundleDocumentTypes 覆盖 Mac 应用程序文件关联

git pull 会导致本地为提交代码被覆盖吗?为啥我从来没出现过,啥情况下才会被覆盖呢?

excel在一列前加相同的文字为啥前一列的文字会被覆盖