Obj-C MyStreamHandler.mm 클래스 파일에 libxml 오류 처리기를 생성하여 할당했습니다. 스트림 파서는 xmlTextReaderSetErrorHandler
를 사용한다. 오류 처리기에서 나는 [NSException raise:format:]
을 사용하여 Obj-C 예외를 발생시킵니다. 그러나 그것의 내에서 Obj-C 클래스 내에서 예외가 catch되지 않습니다. @try/@catch
블록입니다.Obj-C에서 libxml 오류 처리기 콜백 함수 (Obj-C++)에서 Obj-C 예외가 발생했습니다. Obj-C에서 catch되지 않았습니다.
libxml에서 잘못된 xml이 발견되면 (예 : </foo </bar>) 콜백이 발생합니다. 오류 처리기가 많이 호출되고 있으며 NSException
도 발생하는 것으로 알려져 있습니다. 그러나 예외는 libxml의 클라이언트 인 Obj-C 클래스에서 잡히지 않습니다.
<foo><bar</foo>
아래 캐치되지 않는 예외에 의한 관련된 호출 스택의 다음은 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 파일입니다 :
*** 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 예외를 던져서 Obj-C 코드의 정상적인 @ try/@ catch 블록을 통해 처리 할 수 있습니까? 또는 Obj-C++ try/catch 블록을 사용하여 실제 Obj-C++ 예외를 발생시켜야합니까?
도움을 주시면 감사하겠습니다.
우리의 패턴은 파일 판독기에서 예외를 사용하여 응용 프로그램에 제어권을 넘겨주기 전에 패턴을 잡는 것입니다. 그런 다음 NSError **로 변환 한 다음 그 때부터 사용합니다. 크리스에게 감사드립니다. – xmlhack
Java 또는 .NET 플랫폼에서 익숙하지 않은 패턴을 사용하면 안됩니다. 임의의 C 코드에서 예외를 던져 Objective-C 또는 C++에서 catch 할 수는 없습니다. C 코드에서 사용되는 상태가 일관성을 잃어 충돌, 정지, 보안 악용 등이 발생할 수 있습니다. –
임의의 C 코드가 아니며 상태가 일관성이 없습니다. 이것은 Java 또는 .NET 플랫폼에서 사용되지도 않습니다. 이것은 거의 10 년 동안 선적 된 Objective-C 및 Obj-C++ 코드입니다. 우리는 이미 필요한 퍼지 테스트를 수행했습니다. – xmlhack