如何等待 plist 写操作完成?

Posted

技术标签:

【中文标题】如何等待 plist 写操作完成?【英文标题】:How to wait for a plist write operation to complete? 【发布时间】:2014-01-05 18:34:34 【问题描述】:

如何在执行其他操作之前等待 plist 写入操作完成?

// Write plist file
NSString *pathToPlist = [NSString pathWithComponents:@[[Util documentsDirectoryPath], @"Settings.plist"]];
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithContentsOfFile:pathToDocumentsPlist];
[dic setObject:@"SomeObject" @"SomeKey"];
[dic writeToFile:pathToDocumentsPlist atomically:YES];

// Read plist file
NSDictionary *updatedDictionary = [NSDictionary dictionaryWithContentsOfFile: pathToPlist];

在这种情况下,我希望 updatedDictionary 具有更新后的 plist 的值,但是 plist 写入方法 (writeToFile) 似乎是异步的,并且需要很长时间才能完成。结果,updatedDictionary 倾向于读取旧配置,而不是更新配置,因为到 plist 读取时,保存操作尚未完成。

如何解决这个问题?只是纯粹的猜测,设置atomically:NO 可能有帮助吗?谢谢!

【问题讨论】:

writeToFile:atomically: 是同步的,并在方法返回时完成。您发布的代码读取的路径与您写入的路径不同。 pathToPlistpathToDocumentsPlist 似乎都指向同一条路径,尽管它们是 2 个 NSString 对象,但这有关系吗? pathToDocumentsPlist 是较早创建的NSStringpathToPlist 是后来单独创建的。如果writeToFile:atomically: 是同步的,我会尝试自己找出问题所在。谢谢:) 您正在向 NSMutableDictionary 发送消息未知“writeToFile”,因为“writeToFile”方法仅在 NSData 中可用。这是笔误吗? 【参考方案1】:

第一点这个方法不是异步的,它是同步的,它在操作成功与否时返回一个布尔值,所以你可能没有检查它是否被保存,这可能是你的问题。检查writeToFile的返回:原子地:!

现在,一个非常简单的问题,你为什么要这样做?

这是你的代码:

// Write plist file
NSString *pathToPlist = [NSString pathWithComponents:@[[Util documentsDirectoryPath], @"Settings.plist"]];
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithContentsOfFile:pathToDocumentsPlist];
[dic setObject:@"SomeObject" @"SomeKey"];
[dic writeToFile:pathToDocumentsPlist atomically:YES];

// Read plist file
NSDictionary *updatedDictionary = [NSDictionary dictionaryWithContentsOfFile: pathToPlist];

首先,您正在将 plist 读入字典 - 好的

第二次更新字典中的数据 - 好的

第三次,您再次将字典保存到 plist - 好的

第四次你再次获得 plist - 为什么?

您的字典中已经有了 plist 的内容,因为您使用“dic”更新了 plist,那么如果它具有完全相同的 plist 内容,为什么还需要再次阅读? dic 和 plist 在您的代码中是相同的。

如果您想确保内容已保存,方法 writeToFile:atomically 返回一个布尔值,您可以在其中查看操作是否成功。顺便说一句,如果这个方法返回一个布尔值,表示操作已完成,该方法不能是异步的,要异步它应该使用块而不是返回值。

关于“原子”的问题,不,它不会使其同步或异步,以最简单的方式描述它,这原子意味着“没有人”可以访问该文件的内容,直到它完全保存, 所以它会保存在某个临时的地方,当它完成时,它会移动到最终的目的地,所以如果某个对象在它完全保存之前尝试读取/更新/删除它,这是不可能的。

最后试试这个来写你的 plist:

NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

if([dic writeToFile:[documentsDirectory stringByAppendingString:@"/Settings.plist"] atomically:YES])
//it worked

干杯,

罗伯托

【讨论】:

谢谢,我已经解决了这个问题。为了回答这个问题,我使用另一个dictionaryWithContentsOfFile 来获取内容的原因是字典也在其他地方(在另一个线程中)进行了修改。无论如何感谢您的回答!

以上是关于如何等待 plist 写操作完成?的主要内容,如果未能解决你的问题,请参考以下文章

Info.plist:操作无法完成。 (XCBUtil.PropertyListConversionError 错误 0。)

如何等待操作直到使用RXJS完成工作?

如何让 Lambda 函数等待异步操作完成?

Redux thunk:如何等待异步操作的完成

如何在执行下一个操作之前等待请求完成(Xcode 11)

如何等待ajax完成再执行相应操作