2011-02-11 76 views
0

我解析XML与NSXMLParser,我有我的应用程序中的一些NSMutableArrays(实例变量)。当我解析XML文件时,我使用XML元素的值构建对象,并使用这些对象设置我的数组。为什么我的数组显示为空,即使在我向它们添加了值之后?

在我用这些对象设置我的数组的时候,我可以看到它们的值。但是,一旦我完成解析XML我想要检索这些值,现在阵列是空的。

这里是我的代码的一部分:

//STHelpViewController.h 

#import <UIKit/UIKit.h> 

@class SoftokeniPhoneAppDelegate, FAQ; 
@interface STHelpViewController : UIViewController { 
    UIView *viewAnswer; 
    UINavigationBar *answerTitle; 
    UIButton *answerDescription; 
    NSArray *answersArray; 
    NSMutableArray *faqs;  //THIS IS MY ARRAY WITH THE PROBLEM 
    NSMutableString *currentElementValue; 
    FAQ *aFAQ; 

    NSString* Answer1; 
    NSString* Answer2; 
    NSString* Answer3; 
    NSString* Answer4; 
} 

@property (nonatomic, retain) IBOutlet UIView *viewAnswer; 
@property (nonatomic, retain) IBOutlet UINavigationBar *answerTitle; 
@property (nonatomic, retain) IBOutlet UIButton *answerDescription; 
@property (nonatomic, retain) NSMutableArray *faqs; 

@property (nonatomic, retain)NSString* Answer1; 
@property (nonatomic, retain)NSString* Answer2; 
@property (nonatomic, retain)NSString* Answer3; 
@property (nonatomic, retain)NSString* Answer4; 


@end 





//STHelpViewController.m 


- (void)viewDidLoad { 
    [super viewDidLoad]; 
    NSURL *url = [[NSURL alloc] initWithString:@"http://clientes.imit.cl/MovilPass/faq.xml"]; 
    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url]; 

    //Initialize the delegate. 
    STHelpViewController *parser = [[STHelpViewController alloc] initXMLParser]; 

    //Set delegate 
    [xmlParser setDelegate:parser]; 

    //Start parsing the XML file. 
    BOOL success = [xmlParser parse]; 

    if(success){ 
     NSLog(@"F.A.Q. loaded from XMl file"); 

     //HERE IS THE PROBLEM. AT THIS PART XCODE SAYS THAT faqs(my array) IS EMPTY 

     Answer1 = [[[faqs objectAtIndex:0] valueForKey:@"Respuesta"]description]; 
     Answer2 = [[[faqs objectAtIndex:1] valueForKey:@"Respuesta"]description]; 
     Answer3 = [[[faqs objectAtIndex:2] valueForKey:@"Respuesta"]description]; 
     Answer4 = [[[faqs objectAtIndex:3] valueForKey:@"Respuesta"]description]; 
     answersArray = [[NSArray alloc] initWithObjects:Answer1,Answer2,Answer3,Answer4,nil]; 
    } 
    else 
    { 
     NSLog(@"Error loading XML file for F.A.Q. Default data loaded instead."); 
     answersArray = [[NSArray alloc] 
         initWithObjects:@"El Movilpass es una nueva herramienta de Bci Móvil que le permitirá obtener la clave de ocho dígitos desde su celular, sin tener que llevar el dispositivo electrónico. Regístrese para recibir la aplicación, cárguela en su Iphone y sincronícela.", 
         @"El Movilpass es igual de válido que el dispositivo electrónico. Sólo debe sincronizarlo correctamente en su celular, siguiendo uno a uno los pasos que le indiquen.", 
         @"Para sincronizar, presione el botón “Ajustes”, luego “Sincronizar” y obtendrá los siguientes pasos:\n \n Ingrese a su banca Internet. \n Entre a Seguridad y Emergencia. \n Click en Movilpass. \n Seleccione el botón 'Sincronizar'.", 
         @"Si se le perdió su TELEFONO, lo primero que debe hacer es llamar al 600 8242424 para que lo bloqueen. Una vez que obtenga el nuevo aparato, podrá solicitar nuevamente su Movilpass.", 
         nil]; 
    }         
} 


- (STHelpViewController *) initXMLParser { 

    [super init]; 

    //appDelegate = (SoftokeniPhoneAppDelegate *)[[UIApplication sharedApplication] delegate]; 

    return self; 
} 

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
    namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName 
    attributes:(NSDictionary *)attributeDict { 
    if([elementName isEqualToString:@"PreguntasFrecuentes"]) { 
     faqs = [[NSMutableArray new]retain];   
    } 
    else if([elementName isEqualToString:@"Item"]) 
    { 
     aFAQ = [[FAQ alloc] init]; 
     aFAQ.itemID = [[attributeDict objectForKey:@"id"] integerValue];   
     NSLog(@"Leyendo valor de atributo id: %i", aFAQ.itemID); 
    } 
    NSLog(@"Procesando Elemento: %@", elementName); 
} 

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 

    if(!currentElementValue) 
     currentElementValue = [[NSMutableString alloc] initWithString:string]; 
    else 
     [currentElementValue appendString:string]; 

    NSLog(@"Procesando Valor: %@", currentElementValue); 

} 

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
    namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { 

    if([elementName isEqualToString:@"PreguntasFrecuentes"]) 
     return; 
    if([elementName isEqualToString:@"Item"]) { 
     [faqs addObject:aFAQ]; 
     [aFAQ release]; 
     aFAQ = nil; 
    } 
    else 
    { 
     [aFAQ setValue:currentElementValue forKey:elementName];  
    } 
    [currentElementValue release]; 
    currentElementValue = nil; 

    //IF I PRINT MY ARRAY HERE, I CAN SEE THE VALUES 
} 

什么可能我是做错了什么?

+1

请重新格式化您的代码,使压痕是理智的。 – JeremyP

回答

2

您在每个didStartElement调用中实例化faqs = [[NSMutableArray new]retain];。这对我来说似乎很奇怪。您应该将faqs = [[NSMutableArray new]retain];移动到您的viewDidLoad

此外,我没有看到retain那里的必要性。

+0

基本上是这样的:你用每一个parser:didStartElement方法调用不断创建新的faqs实例变量。另外,正如你的标题所指出的那样,当我认为你真的想用它作为属性时,你会使用'faqs'作为一堆新的实例变量,在这种情况下,你应该在设置时指'self.faqs' 。 –

+1

+1:这是完全错误的(代码,而不是你的答案),因为faqs指向的对象每次调用didStartElement时都会泄漏。你是正确的'新'给你所有权,所以没有必要保留。 – JeremyP

+0

这里很好地描述了新的和alloc的init之间的区别:http://stackoverflow.com/questions/719877/use-of-alloc-init-instead-of-new-objective-c –

1

1.在viewDidLoad中,您没有很好的理由分配另一个STHelpViewController。 而是执行此操作,

- (void)viewDidLoad { 
     [super viewDidLoad]; 
     NSURL *url = [[NSURL alloc] initWithString:@"http://clientes.imit.cl/MovilPass/faq.xml"]; 
     NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url]; 
     [url release]; 

     //I am the delegate 
     [xmlParser setDelegate:self]; 

     //Start parsing the XML file. 
     BOOL success = [xmlParser parse]; 

     //NSLog(@"Count My FAQ %d", [[self faqs] count]); Uncomment for debugging. 
     ... 
    } 

2.如果你不使用自己需要修复initXMLParser。您必须始终使用超级班的指定初始化程序并分配给伊娃自己。 像现在这样,

- (STHelpViewController *) initXMLParser { 
     if(self = [super init]) { 
      //alloc and init any ivar you want 
     } 
     return self; 
    } 

然后做到这一点,

- (void)viewDidLoad { 
     [super viewDidLoad]; 
     NSURL *url = [[NSURL alloc] initWithString:@"http://clientes.imit.cl/MovilPass/faq.xml"]; 
     NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url]; 
     [url release]; 

     //Initialize the delegate. 
     STHelpViewController *parser = [[STHelpViewController alloc] initXMLParser]; 

     //Set delegate 
     [xmlParser setDelegate:parser]; 

     //Start parsing the XML file. 
     BOOL success = [xmlParser parse]; 

     //Get results from parser 
     NSArray parserFAQs = [parser faqs]; 
     [parser release]; 

     //NSLog(@"Count Parser's FAQ %d", [parserFAQs count]); Uncomment for debugging. 
     ... 
    } 
相关问题