我有一个OS X应用程序,它使用NSPersistentDocument
的子类来存储数据。 Core Data持久性存储类型是SQLite。我依赖于在Xcode中使用Core Data为基于文档的应用程序创建新项目时创建的标准菜单命令。
此应用程序现在存在了大约两年,并且不断发展。就在今天,我发现"另存为"在我的最新版本中不起作用。行为如下:
我很确定它曾经正常运作。我试过了第一个"官方"我的程序的版本,行为是相同的(错误的)。
编辑:我创建了一个相同类型的新Xcode项目,只有一个Core Data实体。行为是一样的。与我的应用程序的唯一区别是新项目自动使用新的"复制"菜单命令是与10.7 Lion一起引入的,而不是"另存为"。所以我必须按Option键选择"另存为"。
我只在10.9.3上测试过,但在两台不同的Mac上测试过。有没有人知道在哪里看?
编辑2 :它似乎与特定帐户(我在两台计算机上的帐户)相关。它可以在另一个帐户上正常运行。
答案 0 :(得分:1)
我们看到了类似的问题,但仅针对一些用户 - 我们比较了两台机器之间的堆栈跟踪 - 一方面有效,另一方则没有,我们可以看到存在差异。在工作方法上,writeSafely方法使用临时文件,但在非工作版本上不使用临时文件。
这种差异似乎发生在NSDocument的私有方法中,由于某种原因决定不使用临时文件夹。
我们发现如果我们覆盖这个私有方法并将forceTemporaryFile的值设置为YES,那么问题就会消失。
我们不想覆盖这个私有方法,因为我们需要提交到应用商店 - 但这可能对您有用吗?
答案 1 :(得分:1)
对我们来说,虚假行为甚至也出现在二元存储中(我们在应用程序中使用sqlite)。因此,我不认为DTS答案中提到的变化是同一个问题。 (我们目前正在构建10.8-SDK)。此外,这只发生在一些机器上,幸运的是我们现在可以访问它破坏的机器。
对于未记录的方法,覆盖
- (BOOL)_writeSafelyToURL:(NSURL*)url ofType:(NSString*)type forSaveOperation:(NSSaveOperationType)operation forceTemporaryDirectory:(BOOL)forceTemporary error:(NSError **)error
{
return [super _writeSafelyToURL:url ofType:type forSaveOperation:operation forceTemporaryDirectory:YES error:error];
}
总是对forceTemporaryDirectory使用YES: - 参数解决了发生错误的机器上的问题。不建议实际使用,这只是在试图找到问题的原因时。
我也向cocoa-dev-mailing列表发了一个问题:http://lists.apple.com/archives/cocoa-dev/2014/Jun/msg00358.html也许某人有更多的信息。
答案 2 :(得分:0)
Felix Franz在cocoa-dev邮件列表上使用his posting让我走上了正确的轨道:问题与特定的ACL设置有关。我将以下代码添加到NSPersistentDocument
类中以覆盖writeToURL:ofType:forSaveOperation:originalContentsURL:error:
:
- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName forSaveOperation:(NSSaveOperationType)saveOperation originalContentsURL:(NSURL *)absoluteOriginalContentsURL error:(NSError *__autoreleasing *)error {
if ((saveOperation == NSSaveAsOperation) && (absoluteOriginalContentsURL == nil)) {
NSLog(@"---------- absoluteOriginalContentsURL == nil for NSSaveAsOperation ------------");
return [super writeToURL:absoluteURL ofType:typeName forSaveOperation:saveOperation originalContentsURL:self.fileURL error:error];
}
return [super writeToURL:absoluteURL ofType:typeName forSaveOperation:saveOperation originalContentsURL:absoluteOriginalContentsURL error:error];
}
很明显,当self.fileURL
由于某种原因为零时,它为超级方法提供absoluteOriginalContentsURL
。现在"另存为"适用于我测试的所有帐户。