Obj-C MyStreamHandler.mmクラスファイルにlibxmlエラーハンドラを作成して割り当てました。ストリームパーサはxmlTextReaderSetErrorHandler
を使用します。エラーハンドラでは、[NSException raise:format:]
を使用してObj-C例外を発生させています。しかし、例外は私のObj-Cクラスの中でそれが@try/@catch
ブロックに捕らえられていません。Obj-Cのエラーハンドラコールバック関数(Obj-C++)がObj-Cで捕捉されない
無効なxmlが検出された場合(この場合、</foo </bar>)、libxml内でコールバックが発生します。エラーハンドラはそれほど確実であると呼ばれており、NSException
も呼び出されています。しかし、例外はlibxmlのクライアントであるObj-Cクラスでは捕捉されていません。
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のプラットフォームから慣れていないかどうかにかかわらず、そのパターンを使用すべきではありません。 Objective-CやC++で例外を任意のCコードから投げ捨てることはできません。 Cコードで使用されている状態が矛盾している可能性があり、クラッシュ、ハング、セキュリティエクスプロイトなどにつながる可能性があります。 –
これは任意のCコードではなく、状態に矛盾がありません。これは、Javaまたは.NETプラットフォームでの使用でもありません。これは、ほぼ10年間出荷されているObjective-CおよびObj-C++コードです。我々はまた、必要な毛羽立ち検査を既に行っている。 – xmlhack