0

저는 Rest Web service (WCF)를 통해 로그인을 시도하는 iPhone 응용 프로그램을 빌드하고 있습니다. 서비스를 호출하는 부분이 올바르게 작동합니다. 문제없이 호출 된 서비스의 데이터를 수신합니다. 하지만 NSXMLParser를 사용하여 메시지를 구문 분석해야합니다. 응용 프로그램에서 응용 프로그램을 소개 할 때 (응용 프로그램을 처음 사용하는 경우) 응용 프로그램에서 메시지를 올바르게 구문 분석하지만 응용 프로그램 실행이 끝나면 점심 gdb가되고 [풀 드레인] 명령이 시작될 때 응용 프로그램이 일시 중지됩니다. 풀 드레인 명령시 응용 프로그램 시작 디버그

@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

이는 방법 스위 즐링을 사용하여 수행 할 수 있습니다 :

#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 방법에 자신의 코드를 삽입합니다.

도움이 되었기를 바랍니다.

+0

고맙습니다. 그러나 왜이 혼란스런 일을했는지 ​​설명 할 수 있습니까? 드레인 방법을 익히기가 약간 불안하다고 생각합니까? –

+0

어떻게이 주요 기능 당신에게 코드를 사용할 수 있습니다 'int 주 (int argc, 문자의 *의 변수는 argv []) { @autoreleasepool { 반환 UIApplicationMain (는 argc, argv를, 전무, NSStringFromClass ([AppDelegate에 클래스])); } } –

+0

SwizzleMethod ([NSAutoreleasePool 클래스], @selector (drain), @selector (myDrain));와 같은 호출을 사용하면 여전히 작동합니다. 그리고 이미 구현 된 것을 구현하는 가장 쉬운 방법이기 때문에 나는 혼란을 겪었습니다. –