2011-08-10 37 views
1

我在这个问题上已经两天了,无论我做什么,我都无法让它停止泄漏字符串。XML解析类重新运行时发生泄漏字符串

该类是一个XML解析器(使用TouchXML),该解析器设计为在应用程序的整个生命周期中反复运行。它第一次运行,没有泄漏,一切都完美清理。在第二次运行中,它开始泄漏,几乎总是有弦的地方。

从仪器的一些图片:

http://www.producerstudio.net/1.png

http://www.producerstudio.net/2.png

.H

#import <Foundation/Foundation.h> 
#import "TouchXML.h" 

@protocol RSSParsingComplete 
-(void)parsingFinished; 
@end 

@interface RSS : NSObject<NSXMLParserDelegate>{ 
    NSArray *rssURLArray; 
    NSMutableData *xmlData;  
    NSMutableArray *articles; 
    NSMutableArray *arrayOfArticles; 






    int numberOfFeeds; 
    NSDateFormatter *inputFormatter; 
    NSDateFormatter *outputFormatter; 

    id<RSSParsingComplete> delegate; 
} 

@property (nonatomic, retain) NSArray *rssURLArray; 
@property (nonatomic, retain) NSMutableData *xmlData; 
@property (nonatomic, retain) id<RSSParsingComplete> delegate; 

@property (nonatomic, retain) NSMutableArray *articles; 
@property (nonatomic, retain) NSMutableArray *arrayOfArticles; 

@property (nonatomic, retain) NSDateFormatter *inputFormatter; 
@property (nonatomic, retain) NSDateFormatter *outputFormatter; 

-(id)initWithRSSArray:(NSArray *)inputURLArray; 
-(void)connect; 
-(NSArray *)feedArticles; 

@end 

.M

#import "RSS.h" 

@implementation RSS 
@synthesize xmlData, rssURLArray, articles, arrayOfArticles, delegate, inputFormatter, outputFormatter; 

-(void)connect{  
    self.xmlData = [[[NSMutableData alloc] init] autorelease]; 
    NSURL *rssURL = [[NSURL alloc] initWithString:[self.rssURLArray objectAtIndex:numberOfFeeds-1]]; 
    NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:rssURL] delegate:self]; 
    [urlConnection release]; 
    [rssURL release]; 
} 

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ 
    [self.xmlData setLength:0]; 
} 

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

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ 
    [xmlData release]; 
    [connection release]; 
} 

-(void)connectionDidFinishLoading:(NSURLConnection *)connection{ 
    CXMLDocument *xmlDoc = [[[CXMLDocument alloc] initWithData:xmlData options:0 error:nil] autorelease]; 
    self.articles = [[[NSMutableArray alloc] init] autorelease]; 

    self.inputFormatter = [[[NSDateFormatter alloc] init] autorelease]; 
    self.outputFormatter = [[[NSDateFormatter alloc] init] autorelease]; 
    [self.inputFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss zzz"]; 
    [self.inputFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]]; 
    [self.inputFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; 
    [self.outputFormatter setDateFormat:@"dd.MM.yyyy HH:mm:ss"]; 
    [self.outputFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]]; 
    [self.outputFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; 

    NSArray *itemNodes = [xmlDoc nodesForXPath:@"//item" error:nil];  
    for(CXMLElement *node in itemNodes){ 
     NSMutableDictionary *article = [[NSMutableDictionary alloc] init]; 
     for(int counter = 0; counter < [node childCount]; counter++){ 
      if([[[node childAtIndex:counter] name] isEqualToString:@"title"]){ 
       [article setObject:[[node childAtIndex:counter] stringValue] forKey:@"title"]; 
      } 
      if([[[node childAtIndex:counter] name] isEqualToString:@"link"]){ 
       [article setObject:[[node childAtIndex:counter] stringValue] forKey:@"url"]; 
      } 
      if([[[node childAtIndex:counter] name] isEqualToString:@"description"]){ 
       [article setObject:[[node childAtIndex:counter] stringValue] forKey:@"description"]; 
      } 
      if([[[node childAtIndex:counter] name] isEqualToString:@"pubDate"]){ 
       NSDate *tempDate = [self.inputFormatter dateFromString:[[node childAtIndex:counter] stringValue]]; 
       [article setObject:[self.outputFormatter stringFromDate:tempDate] forKey:@"name"]; 
      } 
     } 
     [self.articles addObject:article]; 
     [article release]; 
    } 

    NSArray *feedTitleNode = [xmlDoc nodesForXPath:@"//title" error:nil]; 
    NSString *feedTitle = [[NSString alloc] initWithString:[[[feedTitleNode objectAtIndex:0] childAtIndex:0] stringValue]]; 
    [self.articles addObject:feedTitle]; 
    [feedTitle release]; 

    [self.arrayOfArticles addObject:[articles copy]]; 
    [self.articles removeAllObjects]; 
    [inputFormatter release]; 
    [outputFormatter release]; 
    numberOfFeeds--; 
    if(numberOfFeeds > 0){ 
     [self connect]; 
    }else{ 
     [delegate parsingFinished]; 
    } 
} 



-(NSArray *)feedArticles{  
    NSLog(@"Array of Articles: %@", self.arrayOfArticles); 
    return self.arrayOfArticles; 
} 

-(id)initWithRSSArray:(NSArray *)inputURLArray{ 
    self = [super init]; 
    if (self) {  
     self.arrayOfArticles = [[[NSMutableArray alloc] init] autorelease]; 
     self.rssURLArray = [[[NSArray alloc] initWithArray:inputURLArray] autorelease];  
     numberOfFeeds = [self.rssURLArray count];   
     [self connect]; 
    } 
    return self; 
} 

-(void)dealloc{ 
    [rssURLArray release]; 
    [xmlData release]; 
    [articles release];  
    [arrayOfArticles release]; 
    [super dealloc]; 
} 

- (id)init 
{ 
    self = [super init]; 
    return self; 
} 

@end 

我已经尽全力解决泄漏问题。我已经阅读了Apple内存管理指南以及iPhoneDevSDK上的优秀指南,并且帮助我减少了原来90%的泄漏(只要您一次调用它就不会泄漏)。也许我一直在盯着这个太久,或者我失去了一些明显的东西。

我很感激!

回答

0

首先,应该保留代表?我不确定为什么你需要它作为一个实例变量。但是由于它保留了下来(并且你似乎没有发布它),你的RSS对象将保留对自身的循环引用,并且永远不会被释放。

其次,您是否需要将日期格式化程序保存在实例变量中?看起来你正在分配它们并以相同的方法释放它们。请注意,它们保留在RSS实例中,并且从未发布。