objective-c – 使用NSXMLParser initWithStream:没有收到解析器委托方法

objective-c – 使用NSXMLParser initWithStream:没有收到解析器委托方法,第1张

概述我正在处理的基本问题是使用NSStream类来解析传入的增量 XML数据.数据永远不是一个完整的 XML文档,但我希望根据套接字可以读取的内容以增量块的形式接收和处理它. 查看NSXMLParser的文档,初始化NSXMLParser的initWithStream:方法似乎是我问题的完美解决方案.我可以使用NSInputStream初始化解析器,然后每当我通过socket接收数据时调用NSXMLP 我正在处理的基本问题是使用Nsstream类来解析传入的增量 XML数据.数据永远不是一个完整的 XML文档,但我希望根据套接字可以读取的内容以增量块的形式接收和处理它.

查看NSXMLParser的文档,初始化NSXMLParser的initWithStream:方法似乎是我问题的完美解决方案.我可以使用NSinputStream初始化解析器,然后每当我通过socket接收数据时调用NSXMLParser上的parse方法,而socket应该依次调用NSXMLParser委托.

但是,我没有看到任何被调用的委托,我看到被调用的唯一方法是流委托流:handleEvent:. Apple或其他开发人员似乎很少或没有此API的示例.关于我做错了什么或如何使用initWithStream的任何想法:正确吗?

ContentParser.h

@interface ContentParser : NSObject <NsstreamDelegate,NSXMLParserDelegate>{   NSinputStream *inputStream;   NSOutputStream *outputStream;   NSMutableData *receivedData;   NSXMLParser *xmlParser;}- (voID)initStream;

ContentParser.m

@implementation ContentParser- (voID)initStream{       CFReadStreamRef readStream;   CFWriteStreamRef writeStream;   CFStreamCreatePairWithSocketToHost(kcfAllocatorDefault,(CFStringRef)@"<hostname>",<port>,&readStream,&writeStream);   inputStream = (__brIDge NSinputStream *)readStream;   outputStream = (__brIDge NSOutputStream *)writeStream;   inputStream.delegate = self;   outputStream.delegate = self;   [inputStream  scheduleInRunLoop:[NSRunLoop currentRunLoop]                           forMode:NSDefaultRunLoopMode];   [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]                            forMode:NSDefaultRunLoopMode];   [inputStream open];   [outputStream open];   xmlParser = [[NSXMLParser alloc] initWithStream:inputStream];   [xmlParser setDelegate:self];}- (voID)parser:(NSXMLParser *)parser dIDStartElement:(Nsstring *)elementname                                         namespaceURI:(Nsstring *)namespaceURI                                        qualifIEdname:(Nsstring *)qname                                           attributes:(NSDictionary *)attributeDict{   NSLog(@"dIDStartElement: %@,attributeDict: %@",elementname,attributeDict);}- (voID)parser:(NSXMLParser *)parser foundCharacters:(Nsstring *)string{   NSLog(@"foundCharacters: %@",string);}- (voID)parser:(NSXMLParser *)parser dIDEndElement:(Nsstring *)elementname                                       namespaceURI:(Nsstring *)namespaceURI                                      qualifIEdname:(Nsstring *)qname{   NSLog(@"dIDEndElement: %@",elementname);}- (voID)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{   NSLog(@"Error %ld,Description: %@,line: %ld,Column: %ld",[parseError code],[[parser parserError] localizedDescription],[parser lineNumber],[parser columnNumber]);}- (voID)stream:(Nsstream *)stream handleEvent:(NsstreamEvent)eventCode{   switch (eventCode) {       case NsstreamEventHasBytesAvailable:       {           if (stream == inputStream) {               NSinputStream *is = (NSinputStream *)stream;               if (receivedData == nil) {                   receivedData = [[NSMutableData alloc] init];               }               uint8_t buf[1024];               NSInteger bytesRead = [is read:buf maxLength:1024];               if (bytesRead == -1) {                  NSLog(@"Network read error");               } else if (bytesRead == 0) {                  NSLog(@"No buffer received");               } else {                  [receivedData appendBytes:buf length:bytesRead];                  BOol parserResult = [xmlParser parse];                  if (parserResult == NO) {                     NSLog(@"Unable to parse XML");                  }               }           }           break;       }       default:          break;    }}@end
解决方法 我想出了问题是什么,并在这里回答它,因为将来其他人遇到这个问题,因为[NSXMLParser initWithStream]没有很多文档.

我需要在分配NSXMLParser并将自己设置为委托后立即调用 – [NSXMLParser parse].但因为它是一个同步函数,我需要将它称为另一个线程,所以我不阻塞当前线程,它可以接收Nsstream事件.我也不需要让自己成为NSinputStream的委托.

这可以很简单地使用Grand Central dispatch(GCD)完成,如下所示:

// alloc and init the xml parserxmlParser = [[NSXMLParser alloc] initWithStream:inputStream];[xmlParser setDelegate:self];// block to executedispatch_block_t dispatch_block = ^(voID){    [xmlParser parse];};// create a queue with a unique namedispatch_queue_t dispatch_queue = dispatch_queue_create("parser.queue",NulL);// dispatch queuedispatch_async(dispatch_queue,dispatch_block);// cleanupdispatch_release(dispatch_queue);

这是完整的工作示例,只是因为任何人都无法按照我上面发布的内容.

ContentParser.h

@interface ContentParser : NSObject <NsstreamDelegate,&writeStream);   inputStream = (__brIDge NSinputStream *)readStream;   outputStream = (__brIDge NSOutputStream *)writeStream;   outputStream.delegate = self;   [inputStream  scheduleInRunLoop:[NSRunLoop currentRunLoop]                           forMode:NSDefaultRunLoopMode];   [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]                            forMode:NSDefaultRunLoopMode];   [inputStream open];   [outputStream open];   xmlParser = [[NSXMLParser alloc] initWithStream:inputStream];   [xmlParser setDelegate:self];   dispatch_block_t dispatch_block = ^(voID)   {      [xmlParser parse];   };   dispatch_queue_t dispatch_queue = dispatch_queue_create("parser.queue",NulL);   dispatch_async(dispatch_queue,dispatch_block);   dispatch_release(dispatch_queue);}- (voID)parser:(NSXMLParser *)parser dIDStartElement:(Nsstring *)elementname                                         namespaceURI:(Nsstring *)namespaceURI                                        qualifIEdname:(Nsstring *)qname                                       attributes:(NSDictionary *)attributeDict{   dispatch_block_t dispatch_block = ^(voID)   {      NSLog(@"dIDStartElement: %@,attributeDict);   };   dispatch_queue_t main_queue = dispatch_get_main_queue();   dispatch_async(main_queue,dispatch_block);}- (voID)parser:(NSXMLParser *)parser foundCharacters:(Nsstring *)string{   dispatch_block_t dispatch_block = ^(voID)   {      NSLog(@"foundCharacters: %@",string);   };   dispatch_queue_t main_queue = dispatch_get_main_queue();   dispatch_async(main_queue,dispatch_block);}- (voID)parser:(NSXMLParser *)parser dIDEndElement:(Nsstring *)elementname                                       namespaceURI:(Nsstring *)namespaceURI                                      qualifIEdname:(Nsstring *)qname{   dispatch_block_t dispatch_block = ^(voID)   {      NSLog(@"dIDEndElement: %@",elementname);   };   dispatch_queue_t main_queue = dispatch_get_main_queue();   dispatch_async(main_queue,dispatch_block);}- (voID)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{   dispatch_block_t dispatch_block = ^(voID)   {      NSLog(@"Error %ld,[parser columnNumber]);   };   dispatch_queue_t main_queue = dispatch_get_main_queue();   dispatch_async(main_queue,dispatch_block);}   - (voID)stream:(Nsstream *)stream handleEvent:(NsstreamEvent)eventCode{   switch (eventCode) {      case NsstreamEventHasspaceAvailable:      {         /* write bytes to socket */         break;      }      default:         break;    }}@end
总结

以上是内存溢出为你收集整理的objective-c – 使用NSXMLParser initWithStream:没有收到解析器委托方法全部内容,希望文章能够帮你解决objective-c – 使用NSXMLParser initWithStream:没有收到解析器委托方法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1006028.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存