Я создал обработчик ошибок libxml в файле класса Obj-C MyStreamHandler.mm и назначил его анализатору потока с помощью xmlTextReaderSetErrorHandler
. В обработчике ошибок я поднимаю исключение Obj-C, используя [NSException raise:format:]
. Однако исключение не обнаруживается в моем классе Obj-C в его блоке @try/@catch
.
Обратный вызов запускается, когда встречается недопустимый xml (такой зад </ foo </bar>) внутри libxml. Обработчик ошибок вызывается так, что многое наверняка, и, как известно, NSException
также вызывается. Однако исключение не обнаруживается в моем классе Obj-C, который является клиентом libxml.
MyStreamHandler.mm
#import <libxml/xmlreader.h>
#import "MyStreamHandler.h"
void MyErrorCallback(void *arg, const char *msg, xmlParserSeverities severity, xmlTextReaderLocatorPtr locator);
@implementation MyStreamHandler
-(void)readStream:(xmlTextReaderPtr)streamAPI
{
xmlTextReaderSetErrorHandler(streamAPI, (xmlTextReaderErrorFunc)MyErrorCallback, NULL);
@try
{
while (xmlTextReaderRead(streamAPI) == 1)
{
// Loop through the XML until the malformed XML is hit.
}
}
@catch (id e)
{
NSLog(e);
}
}
@end
void MyErrorCallback(void *arg, const char *msg, xmlParserSeverities severity, xmlTextReaderLocatorPtr locator)
{
[NSException raise:@"MyException" format:@"Something bad happened: %s",msg];
}
Вот пример XML-файла, который вызовет этот обратный вызов и исключение:
<foo><bar</foo>
Ниже приведен связанный стек вызовов, вызванный исключением uncaught :
*** Terminating app due to uncaught exception 'MyException', reason: 'Something bad happened: Opening and ending tag mismatch: content line 0 and container
'
*** Call stack at first throw:
(_NSCallStackArray*)0x10301a40; count=33 {
0 CoreFoundation 0x04324be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x044795c2 objc_exception_throw + 47
2 CoreFoundation 0x042dd628 +[NSException raise:format:arguments:] + 136
3 CoreFoundation 0x042dd59a +[NSException raise:format:] + 58
4 MyApp 0x00ee1b85 _Z25MyErrorCallbackPvPKc19xmlParserSeveritiesS_ + 319
5 libxml2.2.dylib 0x0401766c xmlTextReaderStandalone + 105
6 libxml2.2.dylib 0x04018793 xmlTextReaderSetErrorHandler + 838
7 libxml2.2.dylib 0x03f69c78 __xmlRaiseError + 1222
8 libxml2.2.dylib 0x03f6d564 namePush + 1283
9 libxml2.2.dylib 0x03f75e2c xmlParseXMLDecl + 1291
10 libxml2.2.dylib 0x03f80b6d xmlParseChunk + 3984
11 libxml2.2.dylib 0x0401a255 xmlTextReaderGetAttribute + 816
12 libxml2.2.dylib 0x0401bb34 xmlTextReaderRead + 441
13 MyApp 0x00ec2919 +[MyStreamHandler readStream:]
...
Application call stack
...
24 CoreFoundation 0x0429567d __invoking___ + 29
25 CoreFoundation 0x04295551 -[NSInvocation invoke] + 145
26 Foundation 0x027bd555 -[NSInvocationOperation main] + 51
27 Foundation 0x0272bbd2 -[__NSOperationInternal start] + 747
28 Foundation 0x0272b826 ____startOperations_block_invoke_2 + 106
29 libSystem.B.dylib 0x925a0024 _dispatch_call_block_and_release + 16
30 libSystem.B.dylib 0x925922f2 _dispatch_worker_thread2 + 228
31 libSystem.B.dylib 0x92591d81 _pthread_wqthread + 390
32 libSystem.B.dylib 0x92591bc6 start_wqthread + 30
}
terminate called after throwing an instance of 'NSException'
Это полностью фальшиво? Могу ли я генерировать исключение Obj-C из функции Obj-C ++ и обрабатывать его с помощью обычного блока @ try / @ в моем коде Obj-C? Или мне нужно вызвать фактическое исключение Obj-C ++ с собственным блоком try / catch Obj-C ++?
Любая помощь будет принята с благодарностью.