查看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:没有收到解析器委托方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)