我正在构建一个试图通过Rest Web服务(WCF)执行登录的iPhone应用程序。 调用该服务的部分正常工作。我从被叫服务接收数据没有任何问题。 但我必须使用NSXMLParser解析消息。当我在我的应用程序中引入它时(这是我第一次使用它)应用程序正确解析消息但在应用程序执行结束时它是午餐gdb并在[pool drain]指令开始时暂停应用程序。
@interface MessageParser : NSObject <NSXMLParserDelegate> {
NSMutableString* currentProperty;
Message* message;
}
@property (nonatomic, retain) NSMutableString* currentProperty;
@property (nonatomic, retain) Message* message;
- (void)parseMessageData:(NSData *)data parseError:(NSError **)err;
@end
@implementation MessageParser
@synthesize message, currentProperty;
- (void)parseMessageData:(NSData *)data parseError:(NSError **)err {
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
if (err && [parser parserError]) {
*err = [parser parserError];
}
[parser release];
}
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
if(qName){
elementName = qName;
}
if([elementName isEqualToString:@"Message"]){
self.message = [[Message alloc] init];
}
else if( [elementName isEqualToString:@"body"] || [elementName isEqualToString:@"code"] || [elementName isEqualToString:@"error"]){
currentProperty = [NSMutableString string];
}
}
-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if(qName){
elementName = qName;
}
if(message){
if([elementName isEqualToString:@"body"]){
self.message.messageBody = currentProperty;
}
else if([elementName isEqualToString:@"error"]){
self.message.error = currentProperty;
}
else if([elementName isEqualToString:@"code"]){
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
self.message.messageCode = [f numberFromString:currentProperty];
[f release];
}
}
self.currentProperty = nil;
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)foundedCharacters
{
if (self.currentProperty) {
[currentProperty appendFormat:@"%@", foundedCharacters];
}
}
有时候调试器会给我这样的消息:试图用不在帧中的块创建USE_BLOCK_IN_FRAME变量。
你有什么想法吗?
谢谢。
答案 0 :(得分:1)
这可以使用方法调配来完成:
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface NSAutoreleasePool(customDrain)
-(void) myDrain;
@end
@implementation NSAutoreleasePool(customDrain)
-(void) myDrain
{
if ([self respondsToSelector:@selector(myDrain)])
{
NSLog(@"Draining...");
// note that @selector(myDrain) was remapped
// to @selector(drain) during the process of
// the swizzling, so now, myDrain calls drain,
// and drain calls myDrain.
[self myDrain];
}
else
{
NSLog(@"Remapping Failed!");
}
}
@end
void SwizzleMethod(Class c, SEL orig, SEL new);
void SwizzleMethod(Class c, SEL orig, SEL new) {
Method origMethod = class_getInstanceMethod(c, orig);
Method newMethod = class_getInstanceMethod(c, new);
if (origMethod && newMethod)
method_exchangeImplementations(origMethod, newMethod);
}
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
SwizzleMethod([NSAutoreleasePool class], @selector(drain), @selector(myDrain));
[pool drain];
return 0;
}
您只需将自己的代码放在类别的myDrain方法中,然后在池耗尽时运行自己的代码。
我希望这会有所帮助。