title: Iphone NSXMLParser NSCFString memory leak
body: <p>I am building an app that parses an rss feed.  In the app there are two different types of feeds with different names for the elements in the feed, so I have created an NSXMLParser NSObject that takes the name of the elements of each feed before parsing.  Here is my code:</p>
  
  <p>NewsFeedParser.h</p>
  
  <pre>
  #import 
  
  
  @interface NewsFeedParser : NSObject {
      NSInteger NewsSelectedCategory;
      NSXMLParser *NSXMLNewsParser;
      NSMutableArray *newsCategories;
      NSMutableDictionary *NewsItem;
      NSMutableString *NewsCurrentElement, *NewsCurrentElement1, *NewsCurrentElement2, *NewsCurrentElement3;
      NSString *NewsItemType, *NewsElement1, *NewsElement2, *NewsElement3;
      NSInteger NewsNumElements;
  }
  
  - (void) parseXMLFileAtURL:(NSString *)URL;
  @property(nonatomic, retain) NSString *NewsItemType;
  @property(nonatomic, retain) NSString *NewsElement1;
  @property(nonatomic, retain) NSString *NewsElement2;
  @property(nonatomic, retain) NSString *NewsElement3;
  @property(nonatomic, retain) NSMutableArray *newsCategories;
  @property(assign, nonatomic) NSInteger NewsNumElements;
  
  @end
  
  </pre>
  
  <p>NewsFeedParser.m</p>
  
  <pre>
  #import "NewsFeedParser.h"
  
  
  @implementation NewsFeedParser
  
  @synthesize NewsItemType;
  @synthesize NewsElement1;
  @synthesize NewsElement2;
  @synthesize NewsElement3;
  @synthesize newsCategories;
  @synthesize NewsNumElements;
  
  - (void)parserDidStartDocument:(NSXMLParser *)parser{
  
  }
  
  - (void)parseXMLFileAtURL:(NSString *)URL
  {   
      newsCategories = [[NSMutableArray alloc] init];
  
      URL = [URL stringByReplacingOccurrencesOfString:@" " withString:@""];
      URL = [URL stringByReplacingOccurrencesOfString:@"\n" withString:@""];
      URL = [URL stringByReplacingOccurrencesOfString:@"  " withString:@""];
  
      //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
      [[NSURLCache sharedURLCache] setMemoryCapacity:0];
      [[NSURLCache sharedURLCache] setDiskCapacity:0];
      NSXMLNewsParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
  
      // Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
      [NSXMLNewsParser setDelegate:self];
  
      // Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
      [NSXMLNewsParser setShouldProcessNamespaces:NO];
      [NSXMLNewsParser setShouldReportNamespacePrefixes:NO];
      [NSXMLNewsParser setShouldResolveExternalEntities:NO];
  
      [NSXMLNewsParser parse];
      [NSXMLNewsParser release];
  }
  
  
  - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
      NSString * errorString = [NSString stringWithFormat:@"Unable to download story feed from web site (Error code %i )", [parseError code]];
      NSLog(@"error parsing XML: %@", errorString);
  
      UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:@"Error loading content" message:errorString delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
      [errorAlert show];
      [errorAlert release];
      [errorString release];
  }
  
  
  - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{            
  
      NewsCurrentElement = [elementName copy];
      if ([elementName isEqualToString:NewsItemType]) 
      {
          // clear out our story item caches...
          NewsItem = [[NSMutableDictionary alloc] init];
          NewsCurrentElement1 = [[NSMutableString alloc] init];
          NewsCurrentElement2 = [[NSMutableString alloc] init];
          if(NewsNumElements == 3)
          {
              NewsCurrentElement3 = [[NSMutableString alloc] init];
          }
  
      }
  
  }
  
  - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{     
  
      if ([elementName isEqualToString:NewsItemType]) 
      {
          // save values to an item, then store that item into the array...
          [NewsItem setObject:NewsCurrentElement1 forKey:NewsElement1];
  
          [NewsItem setObject:NewsCurrentElement2 forKey:NewsElement2];
  
          if(NewsNumElements == 3)
          {
              [NewsItem setObject:NewsCurrentElement3 forKey:NewsElement3];
          }
  
          [newsCategories addObject:[[NewsItem copy] autorelease]];
  
          [NewsCurrentElement release];
          [NewsCurrentElement1 release];
          [NewsCurrentElement2 release];
  
          if(NewsNumElements == 3)
          {   
              [NewsCurrentElement3 release];  
          }
  
          [NewsItem release];
  
      }
  
  }
  
  - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
  {
  
      //NSLog(@"found characters: %@", string);
      // save the characters for the current item...
      if ([NewsCurrentElement isEqualToString:NewsElement1]) {
          [NewsCurrentElement1 appendString:string];
      } else if ([NewsCurrentElement isEqualToString:NewsElement2]) {
          [NewsCurrentElement2 appendString:string];
      } else if (NewsNumElements == 3 && [NewsCurrentElement isEqualToString:NewsElement3])
      {
          [NewsCurrentElement3 appendString:string];
      }
  
  }
  
  - (void)dealloc {
      [super dealloc];
  
      [newsCategories release];
      [NewsItemType release];
      [NewsElement1 release];
      [NewsElement2 release];
      [NewsElement3 release];
  
  }
  </pre>
  
  <p>When I create an instance of the class I do like so:</p>
  
  <pre>
      NewsFeedParser *categoriesParser = [[NewsFeedParser alloc] init];
  
      if(newsCat == 0)
      {
          categoriesParser.NewsItemType = @"article";
          categoriesParser.NewsElement1 = @"category";
          categoriesParser.NewsElement2 = @"catid";
      }
      else 
      {
          categoriesParser.NewsItemType = @"article";
          categoriesParser.NewsElement1 = @"category";
          categoriesParser.NewsElement2 = @"feedUrl";
      }
  
  
      [categoriesParser parseXMLFileAtURL:feedUrl];
      newsCategories = [[NSMutableArray alloc] initWithArray:categoriesParser.newsCategories copyItems:YES];
      [self.tableView reloadData];
      [categoriesParser release];
  </pre>
  
  <p>If I run the app with the leaks instrument, the leaks point to the     [NSXMLNewsParser parse] call in the NewsFeedParser.m.</p>
  
  <p>Here is a screen shot of the Leaks instrument with the NSCFStrings leaking:</p>
  
  <p><a href="http://img139.imageshack.us/img139/3997/leaks.png" rel="nofollow noreferrer">http://img139.imageshack.us/img139/3997/leaks.png</a></p>
  
  <p>For the life of me I can't figure out where these leaks are coming from.  Any help would be greatly appreciated.</p>