iCulture forum | iPhone, iPad,  iPod touch, Apple TV en iOS

iCulture forum | iPhone, iPad, iPod touch, Apple TV en iOS (https://forum.iculture.nl/)
-   Ontwikkelen voor iOS (https://forum.iculture.nl/f133/development/f58/ontwikkelen-voor-ios/)
-   -   Problemen met class (https://forum.iculture.nl/f133/development/f58/ontwikkelen-voor-ios/93531-problemen-class.html)

DJ14 17-06-11 17:39

Problemen met class
 
Hallo,

Ik ben al een tijdje bezig met een app waarin gebruik wordt gemaakt van een XML Parser. Het ontwikkelen doe ik in fases, dus ik verbeter de app stukje bij beetje. Nu ben ik bezig om het asynchronous laden van de xml bestanden van het internet te implementeren (ipv synchronous). Hiervoor gebruik ik ASIHTTPRequest. De XMLParser zit verwerkt in een subclass van NSObject, en bevat de NSXMLParserDelegate methods. Nu in deze XML Parser class heb ik de volgende functie staan om het parsen af te handelen (verder staan er nog delegate methods in):

Code:

-(id) loadXMLByArray:(NSArray *)urlArray {
   
    NSLog(@"first call to XML Parser");
   
    if(self.arrayOfObjects){
        [arrayOfObjects removeAllObjects];
        arrayOfObjects = nil;
        [arrayOfObjects release];
    }
   
    if(!self.arrayOfObjects){
        arrayOfObjects = [[NSMutableArray alloc] init];
    }
   
   
    if(context == nil){
        context = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
    }
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"ObjectInfo" inManagedObjectContext:context];
   
    for (NSString *urlString in urlArray){
        NSLog(@"HOI");
        NSURL *url = [[NSURL alloc] initWithString:urlString];
       
        __block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
        [request setCompletionBlock:^{
           
            // Use when fetching binary data
            NSData *responseData = [request responseData];
            NSXMLParser *parser = [[NSXMLParser alloc] initWithData:responseData];
            [parser setDelegate:self];
            [parser setShouldProcessNamespaces:NO]; // We don't care about namespaces
            [parser setShouldReportNamespacePrefixes:NO]; //
            [parser setShouldResolveExternalEntities:NO];
            [parser parse];
            [url release];
            [parser release];
           
           
            if([self.arrayOfObjects count] != 0){
                for(Object *object in self.arrayOfObjects){
                    ObjectInfo *objectInfo = [[ObjectInfo alloc] initWithEntity:entity insertIntoManagedObjectContext:context];
                    objectInfo.ObjectContent = object.content;
                    objectInfo.ObjectDate = object.dateCreated;
                    objectInfo.ObjectUsername = object.userName;
                    objectInfo.ObjectSortDate = object.sortDate;
                   
                    NSURL *url = [NSURL URLWithString:object.urlToImage];
                    NSData *data = [[NSData alloc] initWithContentsOfURL:url];
                    UIImage *uiImage = [UIImage imageWithData:data];
                    [data release];
                    NSData * imageData = UIImagePNGRepresentation(uiImage);
                    objectInfo.ObjectImage = imageData;
                    MyAppDelegate *theDelegate = (MyAppDelegate*)[[UIApplication sharedApplication] delegate];
                    [theDelegate saveContext]; 
                    [objectInfo release];
                }
            }
           
            [self.arrayOfObjects removeAllObjects];
           
        }];
        [request setFailedBlock:^{
            NSError *error = [request error];
            NSLog(@"Error during asynchronous request (ASIHTTPRequest): %@",error);
        }];
        [request startAsynchronous];
       
    }
   
    RootViewController *rVC = [[RootViewController alloc] init];
    [rVC finishFetch];
}

Vanuit een andere class (RootViewController) initaliseer ik deze XMLParser class en start het parsen door het volgende te doen:

Code:

NSArray *arrayWithURLs = [NSArray arrayWithObjects:@"http://somedomain.com/somefeed.xml", @"http://somedomain.com/somesecondfeed", nil];
            XMLParser *xmlParser = [[XMLParser alloc] init];
            [xmlParser loadXMLByArray:arrayWithURLs];

Echter, alles werkt niet zoals het zou moeten werken. Uit de console blijkt dat de functie "loadXMLByArray" uit de XMLParser class veel vaker wordt aangeroepen dan eenmaal. Waarom is dit? Ik roep deze methode immers slechts een keer op vanuit de RootViewController class... Verder blijkt de "arrayOfObjects" ook uit de XMLParser class telkens leeg te zijn. Deze array wordt gevuld door de NSXMLParser delegate methods in de XML Parser class. Waarom wordt deze array niet gewoon gevuld? Het lijkt wel alsof er in de completion block niet gewacht wordt tot het parsen klaar is. Weet iemand wat ik verkeerd doe? (denk zelf dat het iets met die blocks te maken heeft). Bij voorbaat dank.

DJ14 18-06-11 19:06

Opgelost :d:d:d. Toelichting:

Aan het einde van de "loadXMLByArray" functie wordt RootViewController allocated en initialized, terwijl deze al in het geheugen stond. Verder werd de functie "loadXMLByArray" aangeroepen vanuit de viewDidLoad method in de RootViewController class. Door het opnieuw allocaten en initalizen van RootViewController wordt de viewDidLoad method opnieuw geroepen, waardoor "loadXMLByArray" ook opnieuw wordt geroepen. Dit bleef zo doorgaan en resulteert dus in een loop. De oplossing die ik heb geimplementeerd is gebruik van NSNotificationCenter om zo de functie "finishFetch" in RootViewController op te roepen.

XIII 18-06-11 20:39

Slotje dan maar.


Alle tijden zijn GMT +2. Het is nu 22:46.