应用程序在池排水指令处开始调试

时间:2011-12-13 14:18:17

标签: iphone objective-c web-services nsxmlparser nsautoreleasepool

我正在构建一个试图通过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变量。

你有什么想法吗?

谢谢。

1 个答案:

答案 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方法中,然后在池耗尽时运行自己的代码。

我希望这会有所帮助。