简单的文档应用程序,在“恢复到已保存”时抛出异常在 Mac OS X 10.7 Lion 中
我有一个基于文档模板的简单文档应用程序,当在 Mac OS X 10.7 上选择“恢复到已保存 -> 上次打开的版本”菜单项时,该应用程序会引发异常。
异常不在我的代码中,它在 Cocoa 内部。它似乎也与我正在做的任何事情无关。我的应用程序非常简单(在这个阶段),几乎是一个基于普通可可文档的应用程序,基于最新稳定版本 Xcode 中包含的模板。
我意识到这可能是 Lion 中的一个错误,但我需要找到解决方法。
请参阅下面的异常以及我的 NSDocument 子类的全部内容(非常小)。
重现步骤
- 打开任何文档
- ,在文本视图中键入单个字符,
- 选择文件 -> 恢复到已保存
- 单击上次打开的版本
异常
2011-09-04 07:10:29.182 myapp[15433:707] *** -[NSPathStore2 stringByAppendingPathExtension:]: nil argument
2011-09-04 07:10:29.191 myapp[15433:707] (
0 CoreFoundation 0x00007fff89c2b986 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff90c6ed5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff89c2b7ba +[NSException raise:format:arguments:] + 106
3 CoreFoundation 0x00007fff89c2b744 +[NSException raise:format:] + 116
4 Foundation 0x00007fff86d2b172 -[NSPathStore2 stringByAppendingPathExtension:] + 112
5 AppKit 0x00007fff9148f8c3 -[NSDocument _preserveCurrentVersionForReason:error:] + 579
6 AppKit 0x00007fff9147655b __-[NSDocument _revertToVersion:preservingFirst:error:]_block_invoke_3 + 99
7 Foundation 0x00007fff86ef28c3 __-[NSFileCoordinator coordinateReadingItemAtURL:options:error:byAccessor:]_block_invoke_1 + 113
8 Foundation 0x00007fff86ef2f34 -[NSFileCoordinator(NSPrivate) _invokeAccessor:orDont:thenRelinquishAccessClaimForID:] + 202
9 Foundation 0x00007fff86d98a28 -[NSFileCoordinator(NSPrivate) _coordinateReadingItemAtURL:options:error:byAccessor:] + 663
10 Foundation 0x00007fff86ef284c -[NSFileCoordinator coordinateReadingItemAtURL:options:error:byAccessor:] + 79
11 AppKit 0x00007fff91484b41 __-[NSDocument _revertToVersion:preservingFirst:error:]_block_invoke_1 + 347
12 AppKit 0x00007fff914901e3 -[NSDocument performSynchronousFileAccessUsingBlock:] + 42
13 AppKit 0x00007fff9148fc90 -[NSDocument _revertToVersion:preservingFirst:error:] + 125
14 AppKit 0x00007fff91476cf9 -[NSDocument _revertToDiscardRecentChangesPreservingFirst:error:] + 43
15 AppKit 0x00007fff91477094 __-[NSDocument _revertToDiscardRecentChangesThenContinue:]_block_invoke_3 + 164
16 AppKit 0x00007fff91474851 __-[NSDocument performSynchronousFileAccessUsingBlock:]_block_invoke_1 + 19
17 AppKit 0x00007fff91475bda -[NSDocument continueFileAccessUsingBlock:] + 227
18 AppKit 0x00007fff91490413 -[NSDocument _performFileAccessOnMainThread:usingBlock:] + 466
19 AppKit 0x00007fff9149023f -[NSDocument performSynchronousFileAccessUsingBlock:] + 134
20 AppKit 0x00007fff91495891 __-[NSDocument _revertToDiscardRecentChangesThenContinue:]_block_invoke_2 + 301
21 AppKit 0x00007fff914909a9 -[NSDocument _something:wasPresentedWithResult:soContinue:] + 21
22 AppKit 0x00007fff91381bee -[NSAlert didEndAlert:returnCode:contextInfo:] + 93
23 AppKit 0x00007fff9138e356 -[NSApplication endSheet:returnCode:] + 275
24 AppKit 0x00007fff91381ab4 -[NSAlert buttonPressed:] + 265
25 CoreFoundation 0x00007fff89c1b11d -[NSObject performSelector:withObject:] + 61
26 AppKit 0x00007fff911dd852 -[NSApplication sendAction:to:from:] + 139
27 AppKit 0x00007fff911dd784 -[NSControl sendAction:to:] + 88
28 AppKit 0x00007fff911dd6af -[NSCell _sendActionFrom:] + 137
29 AppKit 0x00007fff911dcb7a -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2014
30 AppKit 0x00007fff9125c57c -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 489
31 AppKit 0x00007fff911db786 -[NSControl mouseDown:] + 786
32 AppKit 0x00007fff911a666e -[NSWindow sendEvent:] + 6280
33 AppKit 0x00007fff9113ef19 -[NSApplication sendEvent:] + 5665
34 AppKit 0x00007fff910d542b -[NSApplication run] + 548
35 AppKit 0x00007fff9135352a NSApplicationMain + 867
36 myapp 0x00000001000018d2 main + 34
37 myapp 0x00000001000018a4 start + 52
)
NSDocument 子类
@implementation MyTextDocument
@synthesize textStorage;
@synthesize textView;
+ (BOOL)autosavesInPlace
{
return YES;
}
- (id)init
{
self = [super init];
if (self) {
self.textStorage = nil;
self.textView = nil;
textContentToLoad = [@"" retain];
}
return self;
}
- (NSString *)windowNibName
{
return @"MyTextDocument";
}
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
self.textStorage = self.textView.textStorage;
[self loadTextContentIntoStorage];
}
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
{
return [self.textStorage.string dataUsingEncoding:NSUTF8StringEncoding];
}
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
{
textContentToLoad = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (!textContentToLoad) {
*outError = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileReadUnknownError userInfo:nil];
return NO;
}
[self loadTextContentIntoStorage];
return YES;
}
- (void)loadTextContentIntoStorage
{
if (!self.textStorage || !textContentToLoad)
return;
[self.textStorage beginEditing];
[self.textStorage replaceCharactersInRange:NSMakeRange(0, self.textStorage.length) withString:textContentToLoad];
[textContentToLoad release], textContentToLoad = nil;
}
@end
I have a simple document app, based on the document template, which is throwing an exception when the "Revert to Saved -> Last Opened Version" menu item is selected on Mac OS X 10.7.
The exception isn't in my code, it's inside Cocoa. It also doesn't appear to be related to anything I'm doing. My app is very simple (at this stage), almost a vanilla cocoa document based app, based on the template included with the latest stable version of Xcode.
I realise this is probably a bug in Lion, but I need to find a workaround.
See below for the exception, and the entire contents (very small) of my NSDocument subclass.
Steps to reproduce
- open any document
- type a single character into the text view
- select File -> Revert to Saved
- click Last Opened Version
Exception
2011-09-04 07:10:29.182 myapp[15433:707] *** -[NSPathStore2 stringByAppendingPathExtension:]: nil argument
2011-09-04 07:10:29.191 myapp[15433:707] (
0 CoreFoundation 0x00007fff89c2b986 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff90c6ed5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff89c2b7ba +[NSException raise:format:arguments:] + 106
3 CoreFoundation 0x00007fff89c2b744 +[NSException raise:format:] + 116
4 Foundation 0x00007fff86d2b172 -[NSPathStore2 stringByAppendingPathExtension:] + 112
5 AppKit 0x00007fff9148f8c3 -[NSDocument _preserveCurrentVersionForReason:error:] + 579
6 AppKit 0x00007fff9147655b __-[NSDocument _revertToVersion:preservingFirst:error:]_block_invoke_3 + 99
7 Foundation 0x00007fff86ef28c3 __-[NSFileCoordinator coordinateReadingItemAtURL:options:error:byAccessor:]_block_invoke_1 + 113
8 Foundation 0x00007fff86ef2f34 -[NSFileCoordinator(NSPrivate) _invokeAccessor:orDont:thenRelinquishAccessClaimForID:] + 202
9 Foundation 0x00007fff86d98a28 -[NSFileCoordinator(NSPrivate) _coordinateReadingItemAtURL:options:error:byAccessor:] + 663
10 Foundation 0x00007fff86ef284c -[NSFileCoordinator coordinateReadingItemAtURL:options:error:byAccessor:] + 79
11 AppKit 0x00007fff91484b41 __-[NSDocument _revertToVersion:preservingFirst:error:]_block_invoke_1 + 347
12 AppKit 0x00007fff914901e3 -[NSDocument performSynchronousFileAccessUsingBlock:] + 42
13 AppKit 0x00007fff9148fc90 -[NSDocument _revertToVersion:preservingFirst:error:] + 125
14 AppKit 0x00007fff91476cf9 -[NSDocument _revertToDiscardRecentChangesPreservingFirst:error:] + 43
15 AppKit 0x00007fff91477094 __-[NSDocument _revertToDiscardRecentChangesThenContinue:]_block_invoke_3 + 164
16 AppKit 0x00007fff91474851 __-[NSDocument performSynchronousFileAccessUsingBlock:]_block_invoke_1 + 19
17 AppKit 0x00007fff91475bda -[NSDocument continueFileAccessUsingBlock:] + 227
18 AppKit 0x00007fff91490413 -[NSDocument _performFileAccessOnMainThread:usingBlock:] + 466
19 AppKit 0x00007fff9149023f -[NSDocument performSynchronousFileAccessUsingBlock:] + 134
20 AppKit 0x00007fff91495891 __-[NSDocument _revertToDiscardRecentChangesThenContinue:]_block_invoke_2 + 301
21 AppKit 0x00007fff914909a9 -[NSDocument _something:wasPresentedWithResult:soContinue:] + 21
22 AppKit 0x00007fff91381bee -[NSAlert didEndAlert:returnCode:contextInfo:] + 93
23 AppKit 0x00007fff9138e356 -[NSApplication endSheet:returnCode:] + 275
24 AppKit 0x00007fff91381ab4 -[NSAlert buttonPressed:] + 265
25 CoreFoundation 0x00007fff89c1b11d -[NSObject performSelector:withObject:] + 61
26 AppKit 0x00007fff911dd852 -[NSApplication sendAction:to:from:] + 139
27 AppKit 0x00007fff911dd784 -[NSControl sendAction:to:] + 88
28 AppKit 0x00007fff911dd6af -[NSCell _sendActionFrom:] + 137
29 AppKit 0x00007fff911dcb7a -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2014
30 AppKit 0x00007fff9125c57c -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 489
31 AppKit 0x00007fff911db786 -[NSControl mouseDown:] + 786
32 AppKit 0x00007fff911a666e -[NSWindow sendEvent:] + 6280
33 AppKit 0x00007fff9113ef19 -[NSApplication sendEvent:] + 5665
34 AppKit 0x00007fff910d542b -[NSApplication run] + 548
35 AppKit 0x00007fff9135352a NSApplicationMain + 867
36 myapp 0x00000001000018d2 main + 34
37 myapp 0x00000001000018a4 start + 52
)
NSDocument Subclass
@implementation MyTextDocument
@synthesize textStorage;
@synthesize textView;
+ (BOOL)autosavesInPlace
{
return YES;
}
- (id)init
{
self = [super init];
if (self) {
self.textStorage = nil;
self.textView = nil;
textContentToLoad = [@"" retain];
}
return self;
}
- (NSString *)windowNibName
{
return @"MyTextDocument";
}
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
self.textStorage = self.textView.textStorage;
[self loadTextContentIntoStorage];
}
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
{
return [self.textStorage.string dataUsingEncoding:NSUTF8StringEncoding];
}
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
{
textContentToLoad = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (!textContentToLoad) {
*outError = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileReadUnknownError userInfo:nil];
return NO;
}
[self loadTextContentIntoStorage];
return YES;
}
- (void)loadTextContentIntoStorage
{
if (!self.textStorage || !textContentToLoad)
return;
[self.textStorage beginEditing];
[self.textStorage replaceCharactersInRange:NSMakeRange(0, self.textStorage.length) withString:textContentToLoad];
[textContentToLoad release], textContentToLoad = nil;
}
@end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当涉及到类型时,你的 plist 设置正确吗?
看来 NSDocument 将
[self fileNameExtensionForType:[self auto savingFileType] saveOperation:NSAutosaveElsewhereOperation]
的结果传递给stringByAppendingPathExtension:
(此处抛出异常的方法)。如果您的应用为此表达式返回nil
,则可能会导致此异常。您可能应该为此向 Apple 提交一个错误,但与此同时,请确保您的应用返回非
nil
的内容。Is your plist set up correctly when it comes to types?
It appears that NSDocument passes the result of
[self fileNameExtensionForType:[self autosavingFileType] saveOperation:NSAutosaveElsewhereOperation]
tostringByAppendingPathExtension:
(the method that's throwing the exception here). If your app returnsnil
for this expression, then this exception may result.You should probably file a bug at Apple for this, but in the meantime, make sure your app returns something non-
nil
.将其粘贴到您的文档类中(例如 Document.m):
之前,就像 kperryua 所说,该方法没有实现并返回 nil。
Paste this into you document class (e.g. Document.m):
Before, like kperryua said, this method was not implemented and returned nil.