0

i parsing a XML file. when i adding values into array, the array still null, i don't know the reason. may be reason is that i using this array in two classes. there is .h files

xmlparser.h

#import <UIKit/UIKit.h>

@class SightsTableViewController, Sight;

@interface XMLParser : NSObject {

   NSMutableString *currentElementValue;
   NSMutableArray *allSights;
   NSMutableArray *Arr;
   SightsTableViewController *sightsDelegate;
   Sight *aSight; 
}

- (XMLParser *) initXMLParser; 
- (XMLParser *) arrayResult;

@property (nonatomic, retain) NSMutableArray *allSights;
@end   

SightsTableViewController.h

#import <UIKit/UIKit.h>

@class SightsTableViewController, SightsDetailController;

@interface SightsTableViewController : UITableViewController <UITableViewDelegate>, UITableViewDataSource> {
    IBOutlet UITableView *sightsTableView;
    NSMutableArray *allSights;
    NSMutableArray *Arr;
    SightsDetailController *sightsDetailController;
    SightsTableViewController *sightsDelegate;

 }

 @property (nonatomic, retain) NSMutableArray *allSights;
 @property (nonatomic, retain) NSMutableArray *Arr;
 @property (nonatomic, retain) SightsDetailController *sightsDetailController;


 @end

and .m files

i posting only methods which i using arrays. xmlparser.m

#import "XMLParser.h"
#import "SightsTableViewController.h"
#import "Sight.h"

@implementation XMLParser
@synthesize allSights;
- (XMLParser *) arrayResult {

     Arr = [[NSMutableArray alloc] init];
     [Arr addObject:@"fisrt"];
     [Arr addObject:@"two"];
     [Arr addObject:@"three"];
     [Arr addObject:@"four"];
     [Arr addObject:@"five"];
     NSLog(@"%@", Arr);

     return Arr;
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
   namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName 
 attributes:(NSDictionary *)attributeDict {

        if([elementName isEqualToString:@"Sights"]) {
               //Initialize the array.
                sightsDelegate.allSights = [[NSMutableArray alloc] init];
        }
        else if([elementName isEqualToString:@"Sight"]) {

              //Initialize the sight.
              aSight = [[Sight alloc] init];

              //Extract the attribute here.
              aSight.sightID = [[attributeDict objectForKey:@"id"] integerValue];

              NSLog(@"Reading id value :%i", aSight.sightID);
         }

         NSLog(@"Processing Element: %@", elementName);
 }

 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
 namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

             if([elementName isEqualToString:@"Sights"])
               return;

          //There is nothing to do if we encounter the Sight element here.
          //If we encounter the Sight element howevere, we want to add the sight object to the array
          // and release the object.
          if([elementName isEqualToString:@"Sight"]) {
              //adding values
              [allSights addObject:aSight];

              [aSight release];
              aSight = nil;
          }
          else 
             [aSight setValue:currentElementValue forKey:elementName];

          [currentElementValue release];
          currentElementValue = nil;
  } 
  - (void) dealloc {
      [Arr release]; 
      [aSight release];
      [allSights release];
      [super dealloc];
}

@end

SightsTableViewController.m

#import "SightsTableViewController.h"
#import "SightsDetailController.h"
#import "XMLParser.h"
#import "Sight.h"

@implementation SightsTableViewController
@synthesize sightsDetailController, allSights, Arr;
- (void)viewDidLoad {
         [super viewDidLoad];


         NSURL *url = [[NSURL alloc] initWithString:@"http://onsnab.ru/sights.xml"];
         NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];

         //Initialize the delegate.
         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!!!");

         [[XMLParser alloc] arrayResult];
            //showing NULL :(
         NSLog(@"%@", sightsDelegate.allSights);
         self.navigationItem.title = @"Sights";

   }

  - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
          return [sightsDelegate.allSights count];
  }

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

            static NSString *CellIdentifier = @"Cell";

            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
            if (cell == nil) {
                cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
            }
            NSString *cellValue = [sightsDelegate.allSights objectAtIndex:indexPath.row];
            cell.text = cellValue;

            // Set up the cell
            return cell; 
}

- (void)dealloc {
         [sightsDelegate release];
         [sightsDetailController release];
         [super dealloc];
}


 @end
4
  • Did you tested your code in XCode? Some of your methods are nested to each other, instead of going in succession (- (void)arrayResult and - (void)parser:(NSXMLParser *)parser didStartElement:namespaceURI:qualifiedName:attributes:). Also, please, don't type code as a mess - some formatting and it will be easier to understand your code (and more chances for you, that somebody will help). Commented Jun 21, 2010 at 11:33
  • yes i tested, tha app is laiuching but array is null. ( Commented Jun 21, 2010 at 13:30
  • Is the array you're trying to use in both classes Arr? If so, you never pass it back and forth. Just because it has the same name in two places doesn't make it the same object. Commented Jun 21, 2010 at 14:21
  • yes i know that, so i try to use Arr in other class. as you ca see i call a class [[XMLParser alloc] arrayResult]; to test. it's work. the problem with allSights array, i still cant call it in other class. ( Commented Jun 21, 2010 at 14:32

2 Answers 2

1

Your code is a bit jumbled, so I'm having difficulty reading it. My comments are about how NSArray and Objective-C works more than how your code is written.

An NSArray reference variable will be nil if it is never initialized. You can send a message in Objective-C to a nil reference, and Objective-C won't complain. It won't do anything. This behavior is quite handy in some situations, but quite aggravating in others.

To check if your NSArray is not getting initialzed, put a breakpoint on the lines of code that initialize your NSArray. Then run your app. If it never stops at a breakpoint, you've found your bug.

Sign up to request clarification or add additional context in comments.

2 Comments

i initialized the array. in xmlpaser.m by sightsDelegate.allSights = [[NSMutableArray alloc] init]; the question is how to use array in two classes.
the problem array is allSights.
1

In my experience, when I have mystery arrays and dictionaries that just won't take any values I put in them, I can always trace it back to the structure not having been initialized. Any message sent to a nil object (including -addObject) is a silent no-op. So if things are silently failing, the first thing to be suspicious about is that you're talking to nil.

EDIT:

For instance, let's say you have a view controller that lets you enter text in a UITextField, and adds the string of what you put there into an NSMutableArray. So you might go:

MyViewController.h:

@implementation MyViewController : UIViewController {
   UILabel *textInput;
   NSMutableArray *enteredStrings;
}

@property (nonatomic, retain) IBOutlet UITextField *textInput;
@property (nonatomic, retain) NSMutableArray *enteredStrings;

-(IBAction)addTextToArray:(id *)sender

@end

Then MyViewController.m:

@implementation MyViewController

@synthesize textInput;
@synthesize enteredStrings;

-(void)viewDidLoad
{
//notice the lack of "self.enteredStrings = [NSMutableArray array]" right here!
}

-(IBAction)addTextToArray:(id *)sender
{
    [self.enteredStrings addObject:self.textInput.text];
}

So. That last line won't give you any errors, but it also won't work. [self.enteredStrings count] will stubbornly remain at 0. Because that property points to a nil pointer, not to an NSMutableArray object.

1 Comment

could you please give an example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.