开发者

Why are my arrays showing up as empty, even after I've added values to them?

开发者 https://www.devze.com 2023-02-10 03:59 出处:网络
I am parsing XML with NSXMLParser and I have some NSMutableArrays (instance variables) in my app.When I parse the XML file, I build objects with the values of the XML elements, and set my array with t

I am parsing XML with NSXMLParser and I have some NSMutableArrays (instance variables) in my app. When I parse the XML file, I build objects with the values of the XML elements, and set my array with those objects.

In the moment that I set my array with those objects I can see the values of them. But once I have finished parsing the XML I want to retrieve those values and the array is now empty.

Here is a part of my code:

//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
}

What could I be doing wrong?


You instantiate faqs = [[NSMutableArray new]retain]; on every didStartElement call. It seems weird to me. You should move faqs = [[NSMutableArray new]retain]; to your viewDidLoad.

Moreover, I don't see the necessity of retain there.


1. In viewDidLoad you're allocating another STHelpViewController for no good reason. Do this instead,

    - (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. If you don't use self you have to fix initXMLParser. You must always use the designated initializer of you super class and assign to the ivar self. Like so,

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

And then do this,

    - (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.
        ...
    }
0

精彩评论

暂无评论...
验证码 换一张
取 消