我弄清楚了问题是什么,并在这里回答它,以防其他人将来遇到这个问题+[NSXMLParser initWithStream]
那里没有很多文档。
我需要打电话-[NSXMLParser parse]
在我分配之后NSXMLParser
并指定我自己为代表。但因为它是一个同步函数,所以我需要在另一个线程中调用它,这样我就不会阻塞当前线程并且它可以接收NSStream
事件。我也不需要让自己成为代表NSInputStream
.
使用 Grand Central Dispatch (GCD) 可以非常简单地完成此操作,如下所示:
// alloc and init the xml parser
xmlParser = [[NSXMLParser alloc] initWithStream:inputStream];
[xmlParser setDelegate:self];
// block to execute
dispatch_block_t dispatch_block = ^(void)
{
[xmlParser parse];
};
// create a queue with a unique name
dispatch_queue_t dispatch_queue = dispatch_queue_create("parser.queue", NULL);
// dispatch queue
dispatch_async(dispatch_queue, dispatch_block);
// cleanup
dispatch_release(dispatch_queue);
这是完整的工作示例,以防万一有人无法理解我上面发布的内容。
内容解析器.h
@interface ContentParser : NSObject <NSStreamDelegate,
NSXMLParserDelegate>
{
NSInputStream *inputStream;
NSOutputStream *outputStream;
NSMutableData *receivedData;
NSXMLParser *xmlParser;
}
- (void)initStream;
内容解析器.m
@implementation ContentParser
- (void)initStream
{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,
(CFStringRef)@"<hostname>",
<port>,
&readStream,
&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: %@",
elementName, 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, Description: %@, Line: %ld, Column: %ld",
[parseError code], [[parser parserError] localizedDescription],
[parser lineNumber], [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