2011-02-11 97 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. 
     ... 
    } 
相關問題