Multiple NSXMLParser get "BAD ACCESS" - iphone

i want to read a HTML File with this command:
parseHTML = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:[#"http://theurl.com"]];
[parseHTML setDelegate:self];
[parseHTML parse];
in the didStartElement method i want to stop the actual parser after he found a specified string and parse a new site with these information:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
if(somethingfound)
{
[parseHTML abortParsing];
parseHTML2 = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:[#"http://theurl.com" stringByAppendingString:product_link]]];
[parseHTML2 setDelegate:self];
[parseHTML2 parse];
}
}
i get an irregular error:
Thread1: Program received signal: "EXC
BAD ACCESS"
any ideas?
regards
Hello Walter thanks for your comment, here is the complete implementation:
I hope it helps... :-/
FirstViewController.h
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController <ZBarReaderDelegate, NSXMLParserDelegate>{
UIImageView *resultImage;
UITextView *resultText;
NSString *product_link;
NSXMLParser *parseHTML;
NSXMLParser *parseHTML2;
}
#property (nonatomic, retain) IBOutlet UIImageView *resultImage;
#property (nonatomic, retain) IBOutlet UITextView *resultText;
#property (nonatomic, assign) IBOutlet NSString *product_link;
#property (nonatomic, assign) NSXMLParser *parseHTML;
#property (nonatomic, assign) NSXMLParser *parseHTML2;
#property (nonatomic, retain) NSMutableArray *myMutableArray;
- (IBAction) scanButtonTapped;
#end
FirtViewController.m
#import "FirstViewController.h"
#import "/System/Library/Frameworks/Foundation.framework/Headers/NSDebug.h"
#implementation FirstViewController
#synthesize resultImage, resultText;
#synthesize product_link;
#synthesize parseHTML, parseHTML2;
bool link_is_here = false;
bool allergy_is_here = false;
bool parse_one_ok = true;
int hoch = 0;
- (IBAction) scanButtonTapped
{
NSZombieEnabled = true;
// ADD: present a barcode reader that scans from the camera feed
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
ZBarImageScanner *scanner = reader.scanner;
// TODO: (optional) additional reader configuration here
// EXAMPLE: disable rarely used I2/5 to improve performance
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
// present and release the controller
[self presentModalViewController: reader animated: YES];
[reader release];
}
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id<NSFastEnumeration> results = [info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
break;
// EXAMPLE: do something useful with the barcode data
resultText.text = symbol.data;
parseHTML = [[[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:[#"http://URL.de/suche/?q=" stringByAppendingString:symbol.data]] ]autorelease];
[parseHTML setDelegate:self];
[parseHTML parse];
// [parseHTML release];
// EXAMPLE: do something useful with the barcode image
resultImage.image =
[info objectForKey: UIImagePickerControllerOriginalImage];
// ADD: dismiss the controller (NB dismiss from the *reader*!)
[reader dismissModalViewControllerAnimated: YES];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
for(NSString *key in [attributeDict allKeys]) {
if ([[attributeDict valueForKey:key] isEqualToString:#"some_string"]) {
link_is_here = true;
}
if ([key isEqualToString:#"href"] && link_is_here) {
product_link = [attributeDict valueForKey:key];
// [parseHTML abortParsing];
parseHTML2 = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:[#"http://URL.de" stringByAppendingString:product_link]]];
[parseHTML2 setDelegate:self];
[parseHTML2 parse];
parse_one_ok = true;
link_is_here = false;
}
if ([key isEqualToString:#"id"] && [[attributeDict valueForKey:key] isEqualToString:#"other_string"]) {
allergy_is_here = true;
}
if ([key isEqualToString:#"title"] && allergy_is_here) {
NSLog(#"DO: %#",[attributeDict valueForKey:key]);
}
if ([key isEqualToString:#"id"] && [[attributeDict valueForKey:key] isEqualToString:#"string"]) {
allergy_is_here = false;
parse_one_ok = true;
NSLog(#"Parser off");
//close all parser
}
}
}
-(void) parserDidEndDocument:(NSXMLParser *)parser{
[parseHTML setDelegate:nil];
[parseHTML2 setDelegate:nil];
[parseHTML release];
if (parse_one_ok) {
[parseHTML2 release];
}
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[parseHTML release];
[parseHTML2 release];
self.product_link = nil;
self.resultImage = nil;
self.resultText = nil;
[super dealloc];
}
#end
hey my declaration is in the header:
#interface FirstViewController : UIViewController <NSXMLParserDelegate>{
NSString *product_link;
NSXMLParser *parseHTML;
NSXMLParser *parseHTML2;
}
#property (nonatomic, retain) IBOutlet NSString *product_link;
#property (nonatomic, retain) NSXMLParser *parseHTML;
#property (nonatomic, retain) NSXMLParser *parseHTML2;
and in the source:
#synthesize parseHTML, parseHTML2;
#synthesize product_link;
i get these exception in console:
-[NSCFString setDelegate:]: unrecognized selector sent to instance
0x1acad0

When I have to parse two files at once I set up a second delegate for the second file. The delegate is a simple NSObject that adheres to the NSXML Parser Delegate protocol. (It has the parserDidStart, parserDidEnd, blah blah blah).
Then in my didEndElement of my first parser I kick off the second parser with something like this
SoundCloudParser *scParser = [[[SoundCloudParser alloc] init]autorelease];
NSOperationQueue *queue = [[[NSOperationQueue alloc] init]autorelease];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:scParser selector:#selector(parseXMLUrl:) object:currentArticle.uriString];
[queue addOperation:operation];
[operation release];
I do it on a separate thread which is why you have the queue in there. My 'parseXMLUrl:looks just like a regular one, it just sets the delegate to my second delegate object instead of setting it toself`.
One other thing you need to think about is that you are doing work at the didStartElement and I find that a lot of times I don't have any values in my parsing variables until I get to didEndElement. That would be something else for you to check.
UPDATE: In the future, if you are trying to build on something like ZBarSDK or another project, please say so. It would have saved me about half an hour of messing around with your code.
Basically what we need to do is to set up a new delegate. Let's call it newDelegate. Set it up as a regular NSObject and make it follow <NSXMLDelegate> protocol. It needs a mutableArray or a dictionary to store the data it will parse and it needs a function to kick it off. And that's about it.
So, let's assume you have created newDelegate.h and newDelegate.m in your project and in newDelegate.h you have
#import "Your_App_Delegate.h"
#interface newDelegate : NSObject {
NSMutableString *currentElement;
NSMutableArray *currentArticle;
}
- (void)parseXMLUrl:(NSString *)URL;
#end
So, now in your didStartElement you would call the newDelegate like this:
newDelegate *ndParser = [[[newDelegateParser alloc] init]autorelease];
NSOperationQueue *queue = [[[NSOperationQueue alloc] init]autorelease];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:ndParser selector:#selector(parseXMLUrl:) object:[NSString stringWithFormat:#"http://URL.de/%#",product_link]];
[queue addOperation:operation];
[operation release];
This would kick off the second parser and pass it the url to parse. You will need a way to get that data, so either store some results in your App Delegate or else change the parseXMLURL method of the second parser to return some value.

Related

iphone xml parse not working [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
Please do not close this topic.I really need help.
I am developing on IOS 6.Xcode-4.5.2
On a button click i get the below xml data from the server
<country>america</country>
<dateOfBirth xsi:nil="true"/>
<firstName>John</firstName>
<lastName>Smith</lastName>
<userEmail>johnsmith#email.com</userEmail>
I am trying to parse it and get the values.I did as per the example shown in this url http://www.edumobile.org/iphone/iphone-programming-tutorials/parsing-an-xml-file/
But i am getting an error when the parse method is called.
Instead of the appdelegate class as shown in the example url i am using the viewcontroller class.I do not want to add any code in the Appdelegate class.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AppDelegate setUserDetails:]: unrecognized selector sent to instance 0x9272a40'
I am just a beginner in iphone programming.So i need help in parsing this successfully and i just want to get the values somehow so that i can use them to show on screen in some labels.
Below are codes for 6 files(Viewcontroller.h & m,User.h & m,Xmlparser.h & m)
//ViewController.h
#import <UIKit/UIKit.h>
#import "GlobalVariable.h"
#import "QuotesViewController.h"
#interface ViewController : UIViewController <NSXMLParserDelegate,UIApplicationDelegate,NSStreamDelegate,UIAlertViewDelegate,WriteProtocol>
{
QuotesViewController *quoteobj;
NSMutableArray *userDetails;
}
#property (retain, nonatomic) IBOutlet UITextField *txtUsername;
#property (retain, nonatomic) IBOutlet UITextField *txtPassword;
#property (retain, nonatomic) NSInputStream *inputStream;
#property (retain, nonatomic) NSOutputStream *outputStream;
#property (nonatomic, retain) NSMutableArray *messages;
#property (retain, nonatomic) IBOutlet UILabel *label1;
- (IBAction)btnLogin:(id)sender;
- (IBAction)btnExit:(id)sender;
- (void)initNetworkCommunication;
- (void)readIn:(NSString *)s;
- (void)writeOut:(NSString *)s;
#property (nonatomic, retain) NSMutableArray *userDetails;
#end
//ViewController.m
#import "ViewController.h"
#import "NewTabViewController.h"
#import "QuotesViewController.h"
#import "XMLParser.h"
#implementation ViewController
#synthesize txtPassword,txtUsername,inputStream, outputStream,messages,label1,userDetails;
- (void)viewDidLoad
{
[super viewDidLoad];
quoteobj =[[QuotesViewController alloc]init];
quoteobj.myTableView = [[UITableView alloc]init];
quoteobj.myTableView.delegate=quoteobj;
quoteobj.myTableView.dataSource=quoteobj;
// Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)btnLogin:(id)sender {
NSLog(#"Clicked button1");
[self initNetworkCommunication];
NSString *response = [NSString stringWithFormat:#"POST\r\n\r\nTMS|Login|%#|%#",txtUsername.text,txtPassword.text];
NSLog(#"1");
[self writeOut:response];
}
- (IBAction)btnExit:(id)sender {
exit(0);
}
- (void) initNetworkCommunication {
NSLog(#"initNetworkCommunication called");
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)#"xxx.xxx.x.xx", xxxx, &readStream, &writeStream);
inputStream = (NSInputStream *)readStream;
outputStream = (NSOutputStream *)writeStream;
[inputStream retain];
[outputStream retain];
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
}
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
NSLog(#"stream event %i", streamEvent);
switch (streamEvent) {
case NSStreamEventOpenCompleted:
NSLog(#"Stream opened");
break;
case NSStreamEventHasBytesAvailable:
if (theStream == inputStream) {
uint8_t buffer[1024];
int len;
while ([inputStream hasBytesAvailable]) {
len = [inputStream read:buffer maxLength:sizeof(buffer)];
if (len > 0) {
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
[self readIn:output];
if([output hasPrefix:#"JSESSIONID"]){
int len = [output length];
int lenn = len-29;
sessionId = [output substringWithRange:NSMakeRange(0, lenn)];
label1.text=sessionId;
NSLog(#"New String %# LENGTH SESSUIn %i",sessionId,sessionId.length);
sessionId=label1.text;
NewTabViewController *so = [self.storyboard instantiateViewControllerWithIdentifier:#"newtab"];
for(UIViewController *ssa in so.viewControllers){
if([ssa isKindOfClass:[QuotesViewController class]]){
QuotesViewController *qq = (QuotesViewController *) ssa;
NSLog(#"PREESENTING THIS FZZZZZZZZZZZzzaaadfsdfssdfsa");
[qq setDel:self];
}
}
[self presentViewController:so animated:YES completion:nil];
}
}
}
}
break;
case NSStreamEventErrorOccurred:
NSLog(#"Can not connect to the host!");
UIAlertView *alert =[[UIAlertView alloc]initWithTitle:#"Server says.." message:#"Due to some reason server is unavailable" delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok", nil];
[alert show];
[alert release];
break;
case NSStreamEventEndEncountered:
NSLog(#"NSStreamEventEndEncountered:method is called");
[theStream close];
NSLog(#"theStream is closed");
[theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
NSLog(#"theStream is removed from runloop");
[theStream release];
NSLog(#"theStream is released");
NSLog(#"Server is unavailable");
theStream = nil;
if(theStream==nil){
UIAlertView *alert =[[UIAlertView alloc]initWithTitle:#"Server says.." message:#"Due to some reason server is unavailable" delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok", nil];
[alert show];
[alert release];
}
NSLog(#"IT reaches 1 here");
break;
default:
NSLog(#"Unknown event");
}
}//End of stream
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
NSLog(#"IT reaches here");
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Ok"])
{
NSLog(#"Ok is clicked");
exit(0);
}
}
- (void) messageReceived:(NSString *)message {
NSLog(#"Entered MessageRecieved");
[messages addObject:message];
}
- (void)readIn:(NSString *)s {
NSLog(#"%#", s);
if ([s hasPrefix:#"{"]) {
if([s rangeOfString:#"instrSymbol"].location ==NSNotFound){
NSLog(#"Received a data which is not instrumentid");
}
else{
NSLog(#"JSON DATA RECEIVED");
[quoteobj parseJsonData:s];
}
}
else if([s hasPrefix:#"<"]){
NSLog(#"XML DATA RECEIVED");
NSData *xmlData= [[NSData alloc]initWithData:[s dataUsingEncoding:NSUTF8StringEncoding]];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:xmlData];
XMLParser *parser = [[XMLParser alloc] initXMLParser];
//Set delegate
[xmlParser setDelegate:parser];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success)
NSLog(#"No Errors");
else
NSLog(#"Error Error Error!!!");
}
}
- (void)writeOut:(NSString *)s {
if (outputStream) {
NSLog(#"WRITING OUT");
uint8_t *buf = (uint8_t *)[s UTF8String];
[outputStream write:buf maxLength:strlen((char *)buf)];
NSLog(#"Writing out the following:");
NSLog(#"%#", s);
}
else{
NSLog(#"Noutoyt");
}
}
#end
//XMLParser.h
#import <Foundation/Foundation.h>
#class ViewController,User;
#interface XMLParser : NSObject{
NSMutableString *currentElementValue;
ViewController *zappDelegate;
User *aBook;
}
- (XMLParser *) initXMLParser;
#end
//XMLParser.m
#import "XMLParser.h"
#import "ViewController.h"
#import "User.h"
#implementation XMLParser
- (XMLParser *) initXMLParser {
[super init];
zappDelegate = (ViewController *)[[UIApplication sharedApplication] delegate];
return self;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
if([elementName isEqualToString:#"country"]) {
//Initialize the array.
zappDelegate.userDetails = [[NSMutableArray alloc] init];
}
else if([elementName isEqualToString:#"firstName"]) {
//Initialize the book.
aBook = [[User alloc] init];
//Extract the attribute here.
//aBook.bookID = [[attributeDict objectForKey:#"id"] integerValue];
//NSLog(#"Reading id value :%i", aBook.bookID);
}
NSLog(#"Processing Element: %#", elementName);
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(!currentElementValue)
currentElementValue = [[NSMutableString alloc] initWithString:string];
else
[currentElementValue appendString:string];
NSLog(#"Processing Value: %#", currentElementValue);
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:#"Books"])
return;
if([elementName isEqualToString:#"Book"]) {
[zappDelegate.userDetails addObject:aBook];
[aBook release];
aBook = nil;
}
else
[aBook setValue:currentElementValue forKey:elementName];
[currentElementValue release];
currentElementValue = nil;
}
#end
//User.h
#import <Foundation/Foundation.h>
#interface User : NSObject {
//NSInteger bookID;
NSString *firstName; //Same name as the Entity Name.
NSString *lastName; //Same name as the Entity Name.
NSString *userEmail; //Same name as the Entity Name.
}
#property (nonatomic, retain) NSString *firstName;
#property (nonatomic, retain) NSString *lastName;
#property (nonatomic, retain) NSString *userEmail;
#end
//User.m
#import "User.h"
#implementation User
#synthesize firstName,lastName,userEmail;
- (void) dealloc {
[firstName release];
[lastName release];
[userEmail release];
[super dealloc];
}
#end
You created a class called ViewController but then you try assigning an instance of it in the XMLParser class by casting the application delegate which is unrelated.
zappDelegate = (ViewController *)[[UIApplication sharedApplication] delegate];
You need to change the name of zappDelegate to something more appropriate and assign it a real instance of your ViewController.
I do notice that your ViewController does conform to the UIApplicationDelegate protocol but that does not automatically make it the applications delegate. The real delegate should be properly setup in the main.m[m] file.
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
Check this link i modified the source :
http://dcraziee.wordpress.com/2013/05/29/parsing-xml-in-objective-c/
It will return you the dictionary from your xml response.
All the keys in your xml will be a key and value will in value part of dictionary.
If you contains hierarchal xml then will be managed accordingly.
I hope this will help.

Memory Leak & App Crash when going back to Album List

I'm using three20 to create image viewer. First i'm creating list of albums from the sql db and when user selects any album, its url string is passed to the this code that creates thums of available pics on network using XML Parser. everything works fine but when user goes back to the album list and selects another album. app crashes with 'Thread 1: Program received singal: "EXC+BAD_ACCESS" in main.m. plus XCode Product Analyze gives potential memory leak where i'm creating photoSource in the viewDidLoad. Here is the code
#import "AlbumController.h"
#import "PhotoSource.h"
#import "Photo.h"
#import "AlbumInfo.h"
#import "AlbumDatabase.h"
#implementation AlbumController
#synthesize albumName;
#synthesize urlAddress;
#synthesize images;
- (void)viewDidLoad
{
[super viewDidLoad];
// NSLog(#"%#", self.urlAddress);
[self createPhotos]; // method to set up the photos array
self.photoSource = [[PhotoSource alloc]
initWithType:PhotoSourceNormal
title:self.albumName
photos:images
photos2:nil];
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// release and set to nil
}
-(void)createPhotos
{
if ([stories count] == 0)
{
NSString *path = self.urlAddress;
[self parseXMLFileAtURL:path];
}
images = [NSMutableArray arrayWithCapacity:[stories count]]; // needs to be mutable
for (int i = 0; i < [stories count]; i++)
{
NSString *img = [[stories objectAtIndex:i] objectForKey:#"image"];
img = [img stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
//NSString * caption = [[stories objectAtIndex:i] objectForKey:#"caption"];
//caption = [caption stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
[images addObject:[[[Photo alloc] initWithURL:img smallURL:img size:CGSizeMake(320, 212)] autorelease]];
}
}
#pragma mark -
#pragma mark XML Parser Implementation
- (void)parserDidStartDocument:(NSXMLParser *)parser{
//NSLog(#"found file and started parsing");
}
- (void)parseXMLFileAtURL:(NSString *)URL
{
stories = [[NSMutableArray alloc] init];
//you must then convert the path to a proper NSURL or it won't work
NSURL *xmlURL = [NSURL URLWithString:URL];
// here, for some reason you have to use NSClassFromString when trying to alloc NSXMLParser, otherwise you will get an object not found error
// this may be necessary only for the toolchain
rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
// Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
[rssParser setDelegate:self];
// Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
[rssParser setShouldProcessNamespaces:NO];
[rssParser setShouldReportNamespacePrefixes:NO];
[rssParser setShouldResolveExternalEntities:NO];
[rssParser parse];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSString * errorString = [NSString stringWithFormat:#"Unfortunately it is not possible to load Pictures. Please check Internet Connection. (Error code %i )", [parseError code]];
//NSLog(#"error parsing XML: %#", errorString);
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Failed to load the feed." message:errorString delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
[errorAlert release];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
//NSLog(#"found this element: %#", elementName);
currentElement = [elementName copy];
if ([elementName isEqualToString:#"item"]) {
// clear out our story item caches...
item = [[NSMutableDictionary alloc] init];
currentCaption = [[NSMutableString alloc] init];
//currentThumbnail = [[NSMutableString alloc] init];
currentImage = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
//NSLog(#"ended element: %#", elementName);
if ([elementName isEqualToString:#"item"]) {
// save values to an item, then store that item into the array...
//[item setObject:currentThumbnail forKey:#"thumbnail"];
//[item setObject:currentCaption forKey:#"caption"];
[item setObject:currentImage forKey:#"image"];
[stories addObject:[[item copy] autorelease]];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
// save the characters for the current item...
if ([currentElement isEqualToString:#"thumbnail"]) {
//[currentThumbnail appendString:string];
}// else if ([currentElement isEqualToString:#"caption"]) {
//[currentCaption appendString:string];
//}
else if ([currentElement isEqualToString:#"image"]) {
[currentImage appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
NSLog(#"all done!");
NSLog(#"stories array has %d items", [stories count]);
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
if (toInterfaceOrientation == UIInterfaceOrientationPortrait ||
toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
return YES;
}
else
{
return NO;
}
}
#pragma mark -
#pragma mark Memory Management
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
- (void)dealloc {
[currentElement release];
[rssParser release];
[stories release];
[item release];
[currentCaption release];
//[currentThumbnail release];
[currentImage release];
[images release];
[stories release];
[super dealloc];
}
#end
and here is the didSelectRowAtIndexPath thats pushing this view
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
AlbumInfo *info = [_albumInfos objectAtIndex:indexPath.row];
AlbumController *albumController = [[AlbumController alloc] init];
albumController.urlAddress = info.address;
albumController.albumName = info.name;
[self.navigationController pushViewController:albumController animated:YES];
[albumController release];
}
Here is the code for AlbumController.h
#import <Foundation/Foundation.h>
#import "Three20/Three20.h"
#interface AlbumController : TTThumbsViewController <NSXMLParserDelegate>
{
NSString *albumName;
NSString *urlAddress;
// images
NSMutableArray *images;
// parser
NSXMLParser * rssParser;
NSMutableArray * stories;
NSMutableDictionary * item;
NSString * currentElement;
NSMutableString * currentImage;
NSMutableString * currentCaption;
}
#property (nonatomic, strong) NSString *albumName;
#property (nonatomic, strong) NSString *urlAddress;
#property (nonatomic, retain) NSMutableArray *images;
- (void)createPhotos;
- (void)parseXMLFileAtURL:(NSString *)URL;
#end
used this tutorial http://www.raywenderlich.com/1430/how-to-use-the-three20-photo-viewer
Need help solving this memory leak and need to know why its crashing.
Thanks
Simple. In Xcode 4.0+, Just click-hold on the Run icon, and press Profile. It'll open up Instruments, and you'll want Zombies. Then navigate your app to where the crash happened before, and this time, it'll show up in Instruments with the caller, and all the information about it.
The memory leak in viewDidLoad is caused by the following line:
self.photoSource = [[PhotoSource alloc]
initWithType:PhotoSourceNormal
title:self.albumName
photos:images
photos2:nil];
[PhotoSource alloc] returns an object you own (with a retain count of +1).
initWithType:title:photos:photos2: does not change the retain count.
So viewDidLoad is left with an object it owns, but no pointer to it. To balance the alloc you should send an autorelease message:
self.photoSource = [[[PhotoSource alloc]
initWithType:PhotoSourceNormal
title:self.albumName
photos:images
photos2:nil] autorelease];

Class works not correct. How to make it better?

I have written class and want show it to you ...
I think that this class written not correct and thats why I have leeks in my application. First of all the delloc never calls. What can I change in this class to make it better, please help.
Articles.h
#import <Foundation/Foundation.h>
#interface Article : NSObject {
BOOL favorite;
NSMutableString * title;
NSMutableString * summary;
NSMutableString * mainLink;
NSMutableString * pubDate;
NSMutableString * author;
NSMutableString * imageLink;
}
#property (nonatomic, assign) BOOL favorite;
#property (nonatomic, retain) NSMutableString * title;
#property (nonatomic, retain) NSMutableString * summary;
#property (nonatomic, retain) NSMutableString * mainLink;
#property (nonatomic, retain) NSMutableString * pubDate;
#property (nonatomic, retain) NSMutableString * author;
#property (nonatomic, retain) NSMutableString * imageLink;
- (id)initWithValues:(NSString *) inTitle mainLink:(NSString *) inMainLink summary:(NSString *) inSummary
pubDate:(NSString *) inPubDate author:(NSString *) inAuthor imageLink:(NSString *) inImageLink;
//Setter methods
- (void)setTheTitle:(NSString *) inTitle;
- (void)setTheMainLink:(NSString *) inMainLink;
- (void)setTheSummary:(NSString *) inSummary;
- (void)setThePubDate:(NSString *) inPubDate;
- (void)setTheAuthor:(NSString *) inAuthor;
- (void)setTheImageLink:(NSString *)inImageLink;
#end
Articles.m
#import "Articles.h"
#implementation Article
#synthesize favorite;
#synthesize title;
#synthesize summary;
#synthesize mainLink;
#synthesize pubDate;
#synthesize author;
#synthesize imageLink;
- (void)dealloc {
NSLog(#"article dealloc \n");
[self.title release];
[self.mainLink release];
[self.summary release];
[self.pubDate release];
[self.author release];
[self.imageLink release];
[super dealloc];
}
- (id)init {
self = [super init];
if(self) {
// set your properties...
self.title = [[[NSMutableString alloc] init] autorelease];
self.mainLink = [[[NSMutableString alloc] init] autorelease];
self.summary = [[[NSMutableString alloc] init] autorelease];
self.pubDate = [[[NSMutableString alloc] init] autorelease];
self.author = [[[NSMutableString alloc] init] autorelease];
self.imageLink = [[[NSMutableString alloc] init] autorelease];
self.favorite = NO;
}
return self;
}
- (id)initWithValues:(NSString *) inTitle mainLink:(NSString *) inMainLink summary:(NSString *) inSummary
pubDate:(NSString *) inPubDate author:(NSString *) inAuthor imageLink:(NSString *) inImageLink
{
self = [super init];
if(self) {
// set your properties ...
if (inTitle != nil) {
self.title = inTitle;
}
if (inMainLink != nil) {
self.mainLink = inMainLink ;
}
if (inSummary != nil) {
self.summary = inSummary;
}
if (inPubDate != nil) {
self.pubDate = inPubDate;
}
if (inAuthor != nil) {
self.author = inAuthor ;
}
if (inImageLink != nil) {
self.imageLink = inImageLink ;
}
self.favorite = NO;
}
return self;
}
#end
ADDED:
Look I have NSXMLParser in my main class. In the main class .h file I write:
Article * currentArticle;
Now In .m file when parser didStartElement I alloc ant initialize Article in parser didEndElement I release it [self.currentArticle release]; but delloc not calles.
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
// Copy current Xml Element name.
currentElement = [elementName copy];
if ([elementName isEqualToString:#"item"]) {
// Clear out our story item caches...
self.currentArticle = [[Article alloc] init];
}
[currentElement release];
}
ADDED RELEASE FOR TEST
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
// Copy current Xml Element name.
currentElement = [elementName copy];
if ([elementName isEqualToString:#"item"]) {
// Clear out our story item caches...
self.currentArticle = [[Article alloc] init];
[self.currentArticle release];
}
[currentElement release];
}
look I have added [self.currentArticle release]; right after initialization and put breakpoint here ... When at first time my application enters in this part of code it call init but not call release at second time it call release ? But why ? It's not right
WHY I DON'T USE AUTORELEASE !!!
self.title = [[[NSMutableString alloc] init] autorelease];
self.mainLink = [[[NSMutableString alloc] init] autorelease];
self.summary = [[[NSMutableString alloc] init] autorelease];
self.pubDate = [[[NSMutableString alloc] init] autorelease];
self.author = [[[NSMutableString alloc] init] autorelease];
self.imageLink = [[[NSMutableString alloc] init] autorelease];
I do not use autorelease in this part of code because I have read that it brings to leeks, because when I write autorelease the objects releases in the end of application work ! Am I write ???
Thanks !!!
You can remove every setter like
- (void)setTheSummary:(NSString *) inSummary
{
if (self.summary != nil) {
[self.summary release];
}
self.summary = [[NSMutableString alloc] initWithString:inSummary];
}
You've declared every ivar as property already and synthesized getters and setters. So you can set the title for example with:
self.title = newTitle;
This will retatin the newTitle and assign it to title and release the previous(if present) value.
EDIT
If you set properties like
self.title = [[NSMutableString alloc] init];
the instande of the mutable string will get over retained, so there will be leaks.
Retain increases the retain count by 1, this happens through the property's declaration and it will go one up by calling init.
Change it to:
self.title = [[[NSMutableString alloc] init] autorelease];
EDIT 2
Change your initialization of these constructs:
if (inTitle == nil) {
self.title = [[NSMutableString alloc] init];
}
else
{
[self.title release];
self.title = [[NSMutableString alloc] initWithString:inTitle];
}
To:
if (inTitle != nil) {
self.title = inTitle;
}
Now add
self = [self init];
and remove
[super init];
at the beginning of your init method initWithValues; This will initialize the properties for you first, it reduces code duplication and makes your class smaller. The removal of [super init] is necessary to call the the initializer of NSObject only once, you are doing this by calling self = [self init];.
You've created with this pattern a so called designated initializer. You can read more on initializers here.
EDIT 3
To make your intializers perfect you should write them this way:
- (id)init
{
self = [super init];
if(self) {
// set your properties...
}
return self;
}
and
- (id)initWithValues:(NSString *) inTitle mainLink:(NSString *) inMainLink summary:(NSString *) inSummary
pubDate:(NSString *) inPubDate author:(NSString *) inAuthor imageLink:(NSString *) inImageLink
{
self = [self init];
if(self) {
// set properties with parameters ...
}
return self;
}
This pattern will allow you to react on errors which can occur in your designated initializer and/or in the initializers called up the inheritance hierarchy. This will ensure that a nil is returned if something goes wrong and you don't set properties to an erroneous instance.
For starters I would replace every
if (self.imageLink !=nil) {
[self.imageLink release];
self.imageLink = nil;
}
in dealloc with
[imageLink release];
To help you fix the major issue, that is, why your instance never gets deallocated, we need to see the code where you create it.
Edit
Ok, here is a guess what might be happening. I hope you can use this guess to fix the issue (without seeing the actual code this is all I can do):
Somewhere in you code you have something like this:
Article *article = [[Article alloc] init];
You say you are calling release on the article so you will also have
[article release];
somewhere else in you code.
Now why is dealloc not called even though you call release? My guess is that you are doing something like this in between:
NSMutableArray *array = [NSMutableArray arrayWithCapacity: 0];
[array addObject: article];
This actually retains article and could be the reason why it never gets released. How to fix? Like this:
[array removeObject: article];
Hope this helps.
While there are numerous things going wrong with your code, this is the part which causes memory leaks:
self.title = [[NSMutableString alloc] init];
Why?
The title property is defined as:
#property (nonatomic, retain) NSMutableString * title;
Hence, the setter increases the retain count to 2.
In dealloc retain count for title is only decreased by one, so the object is still alive after deallocing the article.
Quick fix:
self.title = [[[NSMutableString alloc] init] autorelease];
Edit: this is why dealloc never gets called:
self.currentArticle = [[Article alloc] init];
Again, take a look at the retain count: alloc sets retain count to 1.
Then - I assume the currentArticle is defined as (nonatomic, retain) - it is retained again, retain count is now 2. In the dealloc method - I assume again - you release currentArticle, so retain count is 1. An object won't dealloc unless retain count is 0!
Quick fix: same as above
self.currentArticle = [[[Article alloc] init] autorelease];

NSXMLParser multiple call - BAD ACCESS

hello i want to parse html an with this information another html file...
after 1-5 call the program crashes...
header:
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController <ZBarReaderDelegate, NSXMLParserDelegate>{
UIImageView *resultImage;
UITextView *resultText;
NSString *product_link;
NSXMLParser *parseHTML;
NSXMLParser *parseHTML2;
NSMutableArray *myMutableArray;
id <NSXMLParserDelegate> testkollege, asdf;
}
#property (nonatomic, retain) IBOutlet UIImageView *resultImage;
#property (nonatomic, retain) IBOutlet UITextView *resultText;
#property (nonatomic, assign) IBOutlet NSString *product_link;
#property (nonatomic, assign) NSXMLParser *parseHTML;
#property (nonatomic, assign) NSXMLParser *parseHTML2;
#property (nonatomic, retain) NSMutableArray *myMutableArray;
#property (nonatomic, assign) id <NSXMLParserDelegate> testkollege;
#property (nonatomic, assign) id <NSXMLParserDelegate> asdf;
- (IBAction) scanButtonTapped;
#end
m-file:
#import "FirstViewController.h"
#import "/System/Library/Frameworks/Foundation.framework/Headers/NSDebug.h"
#implementation FirstViewController
#synthesize resultImage, resultText;
#synthesize product_link;
#synthesize parseHTML, parseHTML2;
#synthesize myMutableArray;
#synthesize testkollege, asdf;
bool link_is_here = false;
bool allergy_is_here = false;
bool parse_one_ok = true;
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id<NSFastEnumeration> results = [info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
// EXAMPLE: just grab the first barcode
break;
// EXAMPLE: do something useful with the barcode data
resultText.text = symbol.data;
// EXAMPLE: do something useful with the barcode image
resultImage.image =
[info objectForKey: UIImagePickerControllerOriginalImage];
// ADD: dismiss the controller (NB dismiss from the *reader*!)
[reader dismissModalViewControllerAnimated: YES];
parseHTML = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:[#"http://url.com/suche/?q=" stringByAppendingString:symbol.data]] ];
NSLog(#"parser 1 start");
[parseHTML setDelegate:self];
[parseHTML parse];
NSLog(#"parser 1 ready");
[parseHTML release];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
for(NSString *key in [attributeDict allKeys]) {
if ([[attributeDict valueForKey:key] isEqualToString:#"search-result"]) {
link_is_here = true;
}
if ([key isEqualToString:#"href"] && link_is_here) {
product_link = [attributeDict valueForKey:key];
[parser abortParsing];
parseHTML2 = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:[#"http://url.com" stringByAppendingString:product_link]]];
[parseHTML2 setDelegate:self];
parse_one_ok = true;
link_is_here = false;
[parseHTML2 parse];
}
if ([key isEqualToString:#"id"] && [[attributeDict valueForKey:key] isEqualToString:#"nutrition-allergy"]) {
allergy_is_here = true;
}
if ([key isEqualToString:#"title"] && allergy_is_here) {
NSLog(#"keys: %#",[attributeDict valueForKey:key]);
}
if ([key isEqualToString:#"id"] && [[attributeDict valueForKey:key] isEqualToString:#"another string"]) {
allergy_is_here = false;
parse_one_ok = true;
NSLog(#"Parser off");
[parser abortParsing];
}
}
}
-(void) parserDidEndDocument:(NSXMLParser *)parser{
if (parse_one_ok) {
[parseHTML2 release];
parse_one_ok = false;
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[parseHTML release];
[parseHTML2 release];
self.product_link = nil;
self.resultImage = nil;
self.resultText = nil;
[super dealloc];
}
#end
that is simple. You are releasing ParseHTML NSXMLPArsetwice.
-(void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
in the lastline
-(void)dealloc.
A object should be release only if you have earned the ownership. by retain copy etc. But you have allocated it only once so should release only once. But you did two releases .
You are also releasing NSXMLParser object parseHTML2 thrice. As per your code at any stage parseHTML2 will be released at least twice which is retained only once. ParseHTML1 objects case have been mentioned above
Regards,
Jackson Sunny Rodrigues
Turn on NSZombieEnabled. You are obviously releasing something you shouldn't be. When you do this, it will show you exactly where the bad access is occurring and you can trace back to where you are releasing the object. Check out this tutorial:
http://www.codza.com/how-to-debug-exc_bad_access-on-iphone
Best to learn how to fix it and what's wrong :)

iPhone XML parser wont add object to mutable array

Greetings,
I have a problem with adding an object from parser to mutable array.
It was working fine until I moved MtableArray from AppDelegate to ViewController. This is where I call parser (MutableArray is inside this View also):
NSURL *url = [[NSURL alloc] initWithString:#"http://example.com"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
parser = [[XMLParser alloc] init];
[xmlParser setDelegate:parser];
[xmlParser parse];
...and this is inside parser where objects should be added:
if([elementName isEqualToString:#"Element"]) {
[viewController.marray addObject:parsedObj];
[parsedObj release];
parsedObj = nil;
}
marray is synthesized inside viewController. Parser is doing good job, I tried with NSLog, but marray.count is always (null). Please help!!!
Try like this,
[viewController.marray addObject:[parsedObj copy]];
Have you verified that the marray property is non-nil? If it somehow hasn't been set properly then all of the insertions will be no-ops, and the the result of the count method will be nil.
Now that you've posted more code, this line is your problem:
[marray init];
You need to alloc/init a new NSMutableArray; this line is simply sending the init message to nil.
Can you post more code?
If you are inside view controller when marray is being called, you shouldn't have to call viewController.marray, just marray
One suggestion, from my experience in parsing, is to use an NSMutableDictionary instead of an array..so, for instance:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
currentElement = [elementName copy];
if([elementName isEqualToString:#"item"])
{
//Clear out story item caches
item = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
currentAddress = [[NSMutableString alloc] init];
currentCity = [[NSMutableString alloc] init];
currentState = [[NSMutableString alloc] init];
currentZip = [[NSMutableString alloc] init];
currentId = [[NSMutableString alloc] init];
}
}
and then to add everything:
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:#"item"])
{
//Save values to an item, then store that item into the array
[item setObject:currentTitle forKey:#"title"];
[item setObject:currentAddress forKey:#"address"];
[item setObject:currentCity forKey:#"city"];
[item setObject:currentState forKey:#"state"];
[item setObject:currentZip forKey:#"zip"];
[item setObject:currentId forKey:#"id"];
// venues is the mutable array
[venues addObject:[item copy]];
} else {
return;
}
}
Now my mutable array has all the elements I need, and I can do various things with it (like reload a table cell). The above code has been tested and verified as working.
Here is some more code:
ViewController.h
#import <UIKit/UIKit.h>
#class XMLParser;
#interface ViewController : UIViewController{
NSMutableArray *marray;
XMLParser *parser;
}
#property (nonatomic, retain) NSMutableArray *marray;
#property (nonatomic, retain) XMLParser *parser;
#end
ViewController.m
#
import "ViewController.h"
#import "ParsedObj.h"
#import "XMLParser.h"
#synthesize marray;
#synthesize parser;
(...)
-(void)search:(id)sender{
[marray init];
NSURL *url = [[NSURL alloc] initWithString:#"http://example.com"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
parser = [[XMLParser alloc] init];
[xmlParser setDelegate:parser];
[xmlParser parse];
(...)
#end
XMLparser.h:
#import <UIKit/UIKit.h>
#class ViewController, ParsedObj;
#interface XMLParser : NSObject <NSXMLParserDelegate>{
NSMutableString *currentElementValue;
ViewController *viewController;
ParsedObj *parsedObj;
}
#end
..and XMLparser.m:
#import "XMLParser.h"
#import "ViewController.h"
#import "ParsedObj.h"
#implementation XMLParser
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
if([elementName isEqualToString:#"Root"]) {
//Initialize the array.
viewController.marray = [[NSMutableArray alloc] init];
}
else if([elementName isEqualToString:#"Element"]) {
//Initialize the hotel.
parsedObj = [[ParsedObj alloc] init];
//Extract the attribute here.
parsedObj.ID = [[attributeDict objectForKey:#"id"] integerValue];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(!currentElementValue)
currentElementValue = [[NSMutableString alloc] initWithString:string];
else
[currentElementValue appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:#"Root"])
return;
//There is nothing to do if we encounter the Books element here.
//If we encounter the Book element howevere, we want to add the book object to the array
// and release the object.
if([elementName isEqualToString:#"Element"]) {
[accomodationController.marray addObject:parsedObj];
parsedObj = nil;
}
else {
NSString *cValue=[currentElementValue stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[parsedObj setValue:cValue forKey:elementName];
}
[currentElementValue release];
currentElementValue = nil;
}
- (void)dealloc {
[parsedObj release];
[currentElementValue release];
[super dealloc];
}
#end
I tried a different approach and now I have two solutions and a problem with both of them.
I have a XML parser that should add objects to NSMutableArray from where it has been called at first. Parser is working OK, but here is the problem.
First approach:
I changed NSXMLParser's init method inside my XMLParser.m (mArray is for Mutable Array and):
- (XMLParser *) initXMLParser:(id)sender {
[super init];
mArray=(NSMutableArray *)sender;
return self;}
mArray in implementation file XMLParser.h:
#interface XMLParser : NSObject <NSXMLParserDelegate>{
NSMutableString *currentElementValue;
NSMutableArray *mArray;
Object *aObject;}
-(XMLParser *) initXMLParser:(id)sender;
#end
So, let's get to the part where we call XMLParser from ViewController.m:
mArray = [[NSMutableArray alloc] init];
NSURL *url = [[NSURL alloc] initWithString:#"http://www.a.com/some.xml"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
XMLParser *parser = [[XMLParser alloc] initXMLParser:self.mArray];
[xmlParser setDelegate:parser];
[xmlParser parse];
...and here is ViewController.h:
#class XMLParser;
#interface AccomodationSecondViewController : UIViewController{
#public NSMutableArray *mArray;}
#property (nonatomic, retain) NSMutableArray *mArray;
I'm not sure because this is first time I'm using public objects so...
Anyway, this is the part inside XMLParser.m that should add objects:
//This is for closing bracket
if([elementName isEqualToString:#"Element"]) {
[mArray addObject:aObject];
[aObject release];
aObject=nil;}
So, the idea is to make mutable array mArray public inside ViewController and to send pointer to it to XMLParser. I know that this may be little unnatural, but I just want to get it to work.
My other idea is this:
To send pointer of ViewController to XMLParser and do the rest. So, I changed initXMLParser:
- (XMLParser *) initXMLParser:(id)sender {
[super init];
viewController=(ViewController *)sender;
return self;}
and this is the part inside ViewController.m where I call my method:
XMLParser *parser = [[XMLParser alloc] initXMLParser:self];
then I add object:
[viewController.mArray addObject:aObject];
Why is this not working??!!