Vai al contenuto

RISOLTO: Problemi con NSMutableArray


Messaggi raccomandati

Salve, vi espongo il problema.

Ho una classe -A- che espone solo due proprietà: nome e cognome di tipo NSString

In una seconda classe -B- , che importa la classe A, viene parsato un xml che contiene n coppie di nome,cognome; per ogni coppia viene aggiunta una istanza della classe A ad un NSMutableArray -C-. Fino a qui nessun problema, la difficoltà si pone quando devo accedere ai dati contenuti nell'array C; non sono capace.

Sono due giorni che provo svariate soluzione senza ottenere alcun risultato; magari è una stupidaggine ma sono irrimediabilmente bloccato.

Qualcuno può aiutarmi?

Grazie infinite.

L'Uomo in Nero fuggì nel deserto, ed il pistolero lo seguì....

MacBook Pro 15' 2009 - 8 GB RAM / iMac 2011 21,5 - 2,7 GHz - 12 GB RAM / iPod Touch 4th generazione / iPod nano 3th generazione / iPad 1th generazione 32GB

Link al commento
Condividi su altri siti

Scusate, chiarisco meglio il problema postando il codice

Classe A (il .h), la classe si chiama Customer

#import <Foundation/Foundation.h>


@interface Customer : NSObject {

}

@property(retain, nonatomic) NSString *name, *address, *phone;

@end

Chiaramente il .m contiene il @synthesize delle tre variabili

Le cinque prove indicate nel codice sono l'esempio lampante della confusione in cui mi trovo.

Ancora grazie per l'aiuto.

La classe B (il .h), la classe si chiama XMLParsingViewController

#import <UIKit/UIKit.h>
#import "Customer.h"

@interface XMLParsingViewController : UIViewController <NSXMLParserDelegate> {

IBOutlet UIActivityIndicatorView *activityIndicator;
IBOutlet UILabel *name;
IBOutlet UILabel *address;
IBOutlet UILabel *phone;

NSMutableData *customerData;
NSMutableArray *customers;
Customer *customer;
NSString *methodName;
}
- (IBAction)connect:(id)sender;

- (void) startParsing;

@end

Nella classe è presente un bottone che da il via al parsing dell'xml e tre label su cui scrivere nome, indirizzo e telefono.

La classe B (il .m).

#import "XMLParsingViewController.h"

@implementation XMLParsingViewController

- (IBAction)connect:(id)sender {

[customerData release];
customerData = [[NSMutableData alloc] init];

   NSURL *url = [NSURL URLWithString: @"http://indirizzo/prova2.xml"];

NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url];
NSURLConnection *connection = [[NSURLConnection alloc]
							   initWithRequest:request
							   delegate:self];
[connection release];
[request release];
[activityIndicator startAnimating];

}

- (void) startParsing {
NSXMLParser *customerParser = [[NSXMLParser alloc] initWithData:customerData];
customerParser.delegate = self;
[customerParser parse];
[customerParser release];
}

// *******************************************************************************************

#pragma mark NSURLConnection callbacks

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[customerData appendData: data];
}

-(void) connection:(NSURLConnection *)connection
 didFailWithError: (NSError *)error {

UIAlertView *errorAlert = [[uIAlertView alloc]
						   initWithTitle: [error localizedDescription]
						   message: [error localizedFailureReason]
						   delegate:nil
						   cancelButtonTitle:@"OK"
						   otherButtonTitles:nil];

[errorAlert show];
[errorAlert release];
[activityIndicator stopAnimating];
}

- (void) connectionDidFinishLoading: (NSURLConnection*) connection {
NSLog(@"è finito il caricamento e viene richiamanto il parser");
[self startParsing];
[activityIndicator stopAnimating];
}

// *******************************************************************************************

#pragma mark NSXMLParser callbacks

//  Sent by the parser object to the delegate when it begins parsing a document.
- (void)parserDidStartDocument:(NSXMLParser *)parser {
NSLog(@"Inizio il parsing del documento");
}


//  Sent by a parser object to its delegate when it encounters a start tag for a given element.
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {

NSLog(@"elemento letto = %@",elementName);


if ([elementName isEqualToString:@"customers"]) {
	if (customers == nil) {
		customers = [[NSMutableArray alloc]init];  //l'array di destinazione viene allocato
	}
}

if ([elementName isEqualToString:@"customer"]) {
	customer = [Customer alloc];  // si alloca la classe Customer
}

if ([elementName isEqualToString:@"name"]) { 
	methodName = elementName;
}
if ([elementName isEqualToString:@"address"]) { 
	methodName = elementName;
}
if ([elementName isEqualToString:@"phone"]) { 
	methodName = elementName;
}

}

//  Sent by a parser object to provide its delegate with a string representing all or part of the characters of the current element
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {

//NSLog(@"carattere ASSEGNA IL VALORE: %@ AL CAMPO %@", string, [customer description]);

	if ([methodName isEqualToString:@"name"]) {
		customer.name = string;
	}
	if ([methodName isEqualToString:@"address"]) {
		customer.address = string;
	}
	if ([methodName isEqualToString:@"phone"]) {
		customer.phone = string;
	}																
}

//  Sent by a parser object to its delegate when it encounters an end tag for a specific element.
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

NSLog(@"end element %@", elementName);
if ([elementName isEqualToString:@"customer"]) {
	[customers addObject:customer];
	[customer release];
	methodName = nil;
}
}
//  Sent by the parser object to the delegate when it has successfully completed parsing.
- (void)parserDidEndDocument:(NSXMLParser *)parser {

NSLog(@"ho finito di fare il parsing del documento");

       // prova numero 1
//name.text = [customers objectAtIndex:0];  genera eccezione in esecuzione

       // prova numero 2
NSString *test = [customers objectAtIndex:0];
NSLog(@"------%@",test);  // stampa il puntatore del customer del customer ------<Customer: 0x5d258d0>

       // prova numero 3
// queste non possono funzionare, customer non è più allocata
name.text = customer.name;
address.text = customer.address;
phone.text = customer.phone;


       // prova numero 4
Customer *readcustomer = [Customer alloc];

readcustomer = [customers objectAtIndex:0];
NSLog(@"----------------nome %@",readcustomer.name);   // non stampa nulla

       // prova numero 5 
NSObject *item = (NSObject *) [customers objectAtIndex:0];

NSLog(@"-----------------item %@", item);  // stampa il puntatore del customer -----------------item <Customer: 0x5d258d0>

NSLog(@"-----------------item.nome %@", [item valueForKey:@"name"] );  // non stampa nulla

}

I cinque esempi illustrati nel codice sono la prova lampante della confusione in cui mi trovo.

Grazie ancora per l'aiuto

L'Uomo in Nero fuggì nel deserto, ed il pistolero lo seguì....

MacBook Pro 15' 2009 - 8 GB RAM / iMac 2011 21,5 - 2,7 GHz - 12 GB RAM / iPod Touch 4th generazione / iPod nano 3th generazione / iPad 1th generazione 32GB

Link al commento
Condividi su altri siti

Ecco l'errore

2010-09-09 22:35:22.397 XMLParsing[819:207] -[Customer isEqualToString:]: unrecognized selector sent to instance 0x5917670

2010-09-09 22:35:22.400 XMLParsing[819:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Customer isEqualToString:]: unrecognized selector sent to instance 0x5917670'

Grazie.

L'Uomo in Nero fuggì nel deserto, ed il pistolero lo seguì....

MacBook Pro 15' 2009 - 8 GB RAM / iMac 2011 21,5 - 2,7 GHz - 12 GB RAM / iPod Touch 4th generazione / iPod nano 3th generazione / iPad 1th generazione 32GB

Link al commento
Condividi su altri siti

E' strana l'eccezione perchè sembrerebbe non riguardare direttamente il vettore ma invece si riferisce a un argomento non valido del metodo -isEqualToString:...mmm..potrebbe essere una banalità..hai provato a chiamare anche il metodo -init della superclasse NSObject di Customer oltre al semplice +alloc nel momento in cui crei una nuova istanza della classe? Inoltre non mi è molto chiaro il punto in cui dici:

name.text = [customers objectAtIndex:0];

-text restituisce una NSString*, mentre -objectAtIndex: non dovrebbe restituirti Customer*? Io avrei scritto

name.text =[ [customers objectAtIndex:0] name];

address.text =[ [customers objectAtIndex:0] address];

ecc ecc

Fammi sapere!;)

Link al commento
Condividi su altri siti

Da il seguente errore durante l'esecuzione

2010-09-10 00:15:00.316 XMLParsing[2591:207] -[Customer copyWithZone:]: unrecognized selector sent to instance 0x6b2e800

2010-09-10 00:15:00.318 XMLParsing[2591:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Customer copyWithZone:]: unrecognized selector sent to instance 0x6b2e800'

Grazie per la collaborazione.

L'Uomo in Nero fuggì nel deserto, ed il pistolero lo seguì....

MacBook Pro 15' 2009 - 8 GB RAM / iMac 2011 21,5 - 2,7 GHz - 12 GB RAM / iPod Touch 4th generazione / iPod nano 3th generazione / iPad 1th generazione 32GB

Link al commento
Condividi su altri siti

La classe Customer non ha variabili d'istanza o semplicemente è una classe pubblica astratta che fa da cluster a altre classi reali private? Le proprietà che sono dichiarate nell'interfaccia hanno ruolo di varibili condivise da tutte le istanze della classe? Perchè vedendo gli errori che si presentano run-time direi che potrebbero esserci errori nell'implementazione della prima classe.

Link al commento
Condividi su altri siti

Allego la classe customer

Customer.h

#import <Foundation/Foundation.h>


@interface Customer : NSObject {

}

@property(retain, nonatomic) NSString *name, *address, *phone;

@end

Customer.m

#import "Customer.h"


@implementation Customer

@synthesize name, address, phone;

@end

L'Uomo in Nero fuggì nel deserto, ed il pistolero lo seguì....

MacBook Pro 15' 2009 - 8 GB RAM / iMac 2011 21,5 - 2,7 GHz - 12 GB RAM / iPod Touch 4th generazione / iPod nano 3th generazione / iPad 1th generazione 32GB

Link al commento
Condividi su altri siti

In questo modo le usi come variabili globali condivise da tutte le istanze della classe; se invece l'intento era quello di far avere a ciascuna istanza una sua copia di tali variabili allora sarebbe stato meglio dichiarare un'interfaccia del tipo:

#import <Cocoa/Cocoa.h>


@interface Customer : NSObject {

NSString* name;
NSString* address;
NSString* phone;
}
@property (readwrite,retain,nonatomic) NSString* name, address, phone;
-(id)init;
-(id)initWithName:(NSString*)aName withAddress:(NSString*)anAddress withNumber:(NSString*)aPhone;

@end

implementando opportunamente i metodi dichiarati.

Mentre riscrivevo il codice ho notato degli asterischi di troppo nella dichiarazione delle proprietà..prova a togliere l'asterisco di puntatore alle variabili address e phone.

Link al commento
Condividi su altri siti

Che le variabili siano condivise tra tutte le istanze della classe non è un problema.

L'asterisco prima di ogni variabile nella string @property è necessario, altrimenti la compilazione non procede.

Il problema è che non riesco a utlizzare in alcun modo il contenuto dell'array customers riempito nel metodo didEndElement

L'Uomo in Nero fuggì nel deserto, ed il pistolero lo seguì....

MacBook Pro 15' 2009 - 8 GB RAM / iMac 2011 21,5 - 2,7 GHz - 12 GB RAM / iPod Touch 4th generazione / iPod nano 3th generazione / iPad 1th generazione 32GB

Link al commento
Condividi su altri siti

Preso da dubbi amletici, ho effettuato un controllo che avrei dovuto fare ben prima e mi sono accorto che per un mio errore di programmazione non pulivo correttamente una variabile di appoggio; questo provocava la cancellazione del valore letto all'interno dei tag di dati (nome, indirizzo e telefono) e quindi all'interno del array customers scrivevo una stringa vuota con le conseguenza che tutti voi potete immaginare.

In ogni caso ringrazio tutti per l'aiuto dato e principalmente perchè mi avete fatto notare che sbagliavo il modo di lettura dell'array succesivamente al suo riempimento.

L'Uomo in Nero fuggì nel deserto, ed il pistolero lo seguì....

MacBook Pro 15' 2009 - 8 GB RAM / iMac 2011 21,5 - 2,7 GHz - 12 GB RAM / iPod Touch 4th generazione / iPod nano 3th generazione / iPad 1th generazione 32GB

Link al commento
Condividi su altri siti

Archiviato

Questa discussione è archiviata e chiusa a future risposte.

×
×
  • Crea Nuovo...