Утечка строк класса XML в Rerun - PullRequest
1 голос
/ 10 августа 2011

Я занимаюсь этим вопросом уже два дня, и что бы я ни делал, я не могу заставить его прекратить протекать струны.

Этот класс является синтаксическим анализатором 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% утечек, которые у меня были изначально (класс не протекает так долго, как вы его называете один раз). Может быть, я слишком долго на это смотрю, или, может быть, я упускаю что-то очевидное.

Я ценю это!

1 Ответ

0 голосов
/ 17 августа 2011

Во-первых, следует ли делегировать сохранить?Я не уверен, зачем вам это вообще нужно как переменная экземпляра.Но поскольку он сохранен (а вы, кажется, не выпускаете его), ваш объект RSS будет сохранять циклическую ссылку на себя и никогда не будет выпущен.

Во-вторых, вам нужно сохранить средства форматирования датыв переменной экземпляра?Похоже, вы их распределяете и выпускаете одним и тем же способом.Обратите внимание, что они сохраняются в экземпляре RSS и никогда не выпускаются.

...