Ответ 1
Это, похоже, было ошибкой в OS X 10.7 (Lion). С нулевыми изменениями в моем коде, авария больше не происходит на OS X 10.8 (Mountain Lion) соответствует Xcode 4.4.1.
У меня есть подкласс NSDocument для простого текстового редактора (с использованием шаблона приложения Lion new document с несколькими настройками), и я сталкиваюсь с необычной ошибкой, загружающей содержимое файла в текстовое хранилище.
Здесь мой код:
- (void)loadTextContentIntoStorage
{
if (!self.textStorage || !textContentToLoad)
return;
...
[self.textStorage beginEditing];
// NSLog(@"storage: %@ length: %lu textContent: %@", self.textStorage, (unsigned long)self.textStorage.length, textContentToLoad);
// [self.textStorage replaceCharactersInRange:NSMakeRange(0, self.textStorage.length) withString:textContentToLoad];
[self.textStorage replaceCharactersInRange:NSMakeRange(0, 0) withString:@"hello world"];
..
[self.textStorage endEditing];
}
Ошибка происходит, когда I:
Сбой в -replaceCharactersInRange:withString:
с помощью "Невозможно преобразовать байты в строке 0x10004d430 в _NSCStringEncoding".
Но это происходит только при каждом втором запуске приложения (третий запуск не будет аварийно завершен, и он автоматически откроет документ, который он разбил, пытаясь открыть предыдущее время). Это также происходит, когда я запускаю приложение из Xcode. Релиз сборки никогда не разбивались при запуске.
Я думал, что это может быть проблема с кодировкой с системой автоматического сохранения, но даже сбой, когда я комментирую этот код и просто загружаю строку @hello world в текстовое представление (как показано в приведенном выше коде). Аналогично, прокомментированный NSLog()
не показывает ничего странного. Хранилище текста является допустимым (загружается из файла xib), длина хранения текста равна 0, а textContent - это содержимое открытого файла.
--- EDIT ---
Я узнал, что эта проблема каким-то образом связана с правом com.apple.security.app-sandbox
. Если права/песочница включены, мое приложение не. Если права или функция app-песочницы отключены, тогда мое приложение сбрасывается при каждом втором запуске, пытаясь восстановить ранее открытые документы.
Я только заметил, что он сбой при выполнении сборки/запуска изнутри xcode, потому что это была моя единственная конфигурация сборки с отключенной песочницей.
---/EDIT ---
Есть ли у кого-нибудь идеи? Полное исключение следует, и полный исходный код находится в github: https://github.com/abhibeckert/Dux/blob/master/Dux/DuxTextView.m
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Unable to convert bytes in string 0x10004d430 to _NSCStringEncoding'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff84afb286 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff88991d5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff84afb0ba +[NSException raise:format:arguments:] + 106
3 CoreFoundation 0x00007fff84afb044 +[NSException raise:format:] + 116
4 Foundation 0x00007fff835bfae4 copyFromStringToStorage + 262
5 Foundation 0x00007fff835bf979 -[NSBigMutableString replaceCharactersInRange:withString:] + 1000
6 Foundation 0x00007fff835bc3f7 -[NSConcreteMutableAttributedString replaceCharactersInRange:withString:] + 375
7 AppKit 0x00007fff86149e14 -[NSConcreteTextStorage replaceCharactersInRange:withString:] + 81
8 Dux 0x0000000100002f9a -[MyTextDocument loadTextContentIntoStorage] + 1338
9 Dux 0x00000001000022a0 -[MyTextDocument windowControllerDidLoadNib:] + 640
10 AppKit 0x00007fff860f1328 -[NSWindowController _windowDidLoad] + 667
11 AppKit 0x00007fff860e89a3 -[NSWindowController window] + 109
12 AppKit 0x00007fff8615d761 -[NSDocument windowForSheet] + 86
13 AppKit 0x00007fff860e82c4 -[NSDocument _shouldShowAutosaveButtonForWindow:] + 50
14 AppKit 0x00007fff860e7fbb -[NSWindowController setDocument:] + 237
15 AppKit 0x00007fff8629c9b6 -[NSDocument makeWindowControllers] + 139
16 AppKit 0x00007fff8615d555 -[NSDocument(NSPersistentUISupport) restoreDocumentWindowWithIdentifier:state:completionHandler:] + 90
17 AppKit 0x00007fff8615d4aa -[NSDocumentControllerPersistentRestoration loadedDocument:forAutoID:] + 179
18 AppKit 0x00007fff8615cfbe __-[NSDocumentController reopenDocumentForURL:withContentsOfURL:display:completionHandler:]_block_invoke_8 + 187
19 AppKit 0x00007fff86148e14 __-[NSDocumentController reopenDocumentForURL:withContentsOfURL:display:completionHandler:]_block_invoke_5 + 163
20 AppKit 0x00007fff86148d5f __-[NSDocumentController reopenDocumentForURL:withContentsOfURL:display:completionHandler:]_block_invoke_4 + 697
21 AppKit 0x00007fff86148aa1 -[NSDocumentController _openDocumentWithContentsOfURL:usingProcedure:] + 530
22 AppKit 0x00007fff8614868d __-[NSDocumentController reopenDocumentForURL:withContentsOfURL:display:completionHandler:]_block_invoke_3 + 242
23 libdispatch.dylib 0x00007fff8bbbe8ba _dispatch_call_block_and_release + 18
24 libdispatch.dylib 0x00007fff8bbc072a _dispatch_main_queue_callback_4CF + 308
25 CoreFoundation 0x00007fff84a904dc __CFRunLoopRun + 1724
26 CoreFoundation 0x00007fff84a8fae6 CFRunLoopRunSpecific + 230
27 HIToolbox 0x00007fff8852f3d3 RunCurrentEventLoopInMode + 277
28 HIToolbox 0x00007fff8853663d ReceiveNextEventCommon + 355
29 HIToolbox 0x00007fff885364ca BlockUntilNextEventMatchingListInMode + 62
30 AppKit 0x00007fff85ef23f1 _DPSNextEvent + 659
31 AppKit 0x00007fff85ef1cf5 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 135
32 AppKit 0x00007fff85eee62d -[NSApplication run] + 470
33 AppKit 0x00007fff8616d80c NSApplicationMain + 867
34 Dux 0x0000000100001e32 main + 34
35 Dux 0x0000000100001e04 start + 52
36 ??? 0x0000000000000003 0x0 + 3
)
Это, похоже, было ошибкой в OS X 10.7 (Lion). С нулевыми изменениями в моем коде, авария больше не происходит на OS X 10.8 (Mountain Lion) соответствует Xcode 4.4.1.
Я признаю, что этот вопрос натолкнул меня на некоторое время. Я думаю, что, наконец, я нашел ревью.
Просматривая GNUstep код, который эмулирует это поведение, я нашел следующий исходный код:
if (enc == NSASCIIStringEncoding
&& isByteEncoding(internalEncoding))
{
unsigned i;
if (bytes > self->_count)
{
bytes = self->_count;
}
for (i = 0; i < bytes; i++)
{
unsigned char c = self->_contents.c[i];
if (c > 127)
{
[NSException raise: NSCharacterConversionException
format: @"unable to convert to encoding"];
}
buffer[i] = c;
}
buffer[bytes] = '\0';
if (bytes < self->_count)
{
return NO;
}
return YES;
}
...
Очевидно, что этот код не является индивидуальным с вашим сообщением об ошибке. Однако я отмечаю это из вашей ошибки:
reason: 'Unable to convert bytes in string 0x10004d430 to
_NSCStringEncoding'
Ну, мы все знаем, что такое C String, и если вы используете неправильный метод кодирования (например, Wide, где ожидается ASCII или наоборот), вы получите именно эту проблему. Таким образом: попробовали ли вы использовать различные типы данных ASCII и Wide в своем приложении, чтобы исправить эту проблему?
Из-за того, насколько распространено это поведение, это очень вероятно указывает на то, что это обработанный случай с помощью изолированной программной среды приложения. Однако я пока не могу найти документацию. Это должно быть явно отмечено sandboxd
, как я поднял в вопросе errata.
Я получил такое же исключение в 10.9.2.
Unable to convert bytes in string 0x60800026cd40 to _NSCStringEncoding
(
0 CoreFoundation 0x00007fff8dec825c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff81de0e75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8dec810c +[NSException raise:format:] + 204
3 Foundation 0x00007fff8d94dd2b copyFromStringToStorage + 223
4 Foundation 0x00007fff8d94db9e -[NSBigMutableString replaceCharactersInRange:withString:] + 1081
5 Foundation 0x00007fff8d94d738 -[NSConcreteMutableAttributedString replaceCharactersInRange:withAttributedString:] + 296
6 AppKit 0x00007fff88d7889c -[NSConcreteTextStorage replaceCharactersInRange:withAttributedString:] + 77
9 myApp 0x00000001035d3fff myApp + 12287
10 CoreFoundation 0x00007fff8de96e0c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
11 CoreFoundation 0x00007fff8dd8a82d _CFXNotificationPost + 2893
12 Foundation 0x00007fff8d8f8e4a -[NSNotificationCenter postNotificationName:object:userInfo:] + 68
13 AppKit 0x00007fff88b99cde -[NSApplication finishLaunching] + 440
14 AppKit 0x00007fff88b997f3 -[NSApplication run] + 128
15 AppKit 0x00007fff88b84783 NSApplicationMain + 940
16 libdyld.dylib 0x00007fff81aa65fd start + 1
17 ??? 0x0000000000000001 0x0 + 1
)
Я использовал NSTextStorage
в applicationWillFinishLaunching
. Я переместил это на applicationDidFinishLaunching
и его работоспособность.