2009-11-04 19 views
0

我開發了我的iPhone應用程序,現在我正在用儀器測試它以發現內存泄漏。任何人都可以識別泄漏,幫助?

我有我的AppDelegate類中,我從網絡服務中獲取數據,然後分析它,然後將它存儲在陣列..

這裏是我的applicationDidFinishLaunching方法:

UIApplication* app = [UIApplication sharedApplication]; 
app.networkActivityIndicatorVisible = YES; 
serviceURL = [[NSUserDefaults standardUserDefaults] stringForKey:@"readOnly_key"]; 
NSLog(@"text = %@",serviceURL); 

if(serviceURL == nil) 
{ 
    //We set the default values from the settings bundle. 

    //Get the bundle path 
    NSString *bPath = [[NSBundle mainBundle] bundlePath]; 
    NSString *settingsPath = [bPath stringByAppendingPathComponent:@"Settings.bundle"]; 
    NSString *plistFile = [settingsPath stringByAppendingPathComponent:@"Root.plist"]; 

    NSDictionary *settingsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistFile]; 
    NSArray *preferencesArray = [settingsDictionary objectForKey:@"PreferenceSpecifiers"]; 

    NSDictionary *item; 

    NSString *textEntry_Key; 
    NSString *readOnly_Key; 


    for(item in preferencesArray) 
    { 
     //Get the key of the item. 
     NSString *keyValue = [item objectForKey:@"Key"]; 

     //Get the default value specified in the plist file. 
     id defaultValue = [item objectForKey:@"DefaultValue"]; 

     if([keyValue isEqualToString:@"textEntry_key"]){ 
      textEntry_Key = defaultValue; 

     } 

     NSLog(@"default value = %@",defaultValue); 
     if([keyValue isEqualToString:@"readOnly_key"]) 
      readOnly_Key = defaultValue; 



    } 

    //Now that we have all the default values. 
    //We will create it here. 
    NSDictionary *appPrerfs = [NSDictionary dictionaryWithObjectsAndKeys: 
           textEntry_Key, @"textEntry_key", 
           readOnly_Key, @"readOnly_key", 

           nil]; 

    [[NSUserDefaults standardUserDefaults] registerDefaults:appPrerfs]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 

} 

NSURL *url5 = [[NSURL alloc] initWithString:@"http://192.168.0.150/Nirmal/Service.asmx/searchParameterList"]; 
//NSURL *url5 = [[NSURL alloc] initWithString:[NSString stringWithFormat:@"%@/Service.asmx/searchParameterList"]]; 
NSMutableURLRequest* request6=[NSMutableURLRequest requestWithURL:url5]; 
[request6 setHTTPMethod:@"POST"]; 
[request6 setTimeoutInterval:10]; 
//NSURLResponse *response6=nil; 
// NSError *err6=nil; 
    //NSData *data6=[[NSURLConnection sendSynchronousRequest:request6 returningResponse:&response6 error:&err6] retain]; 
    data2=[NSURLConnection sendSynchronousRequest:request6 returningResponse:nil error:nil]; 
    if(data2 == nil) 
    { 
     UIAlertView* alert = [[UIAlertView alloc]initWithTitle:@"Alert" message:@"The network is not available.\n Please check the Internet connection." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
     [alert show]; 
     [alert release]; 

    } 
    else 
    { 
     NSXMLParser *xmlParser5 = [[NSXMLParser alloc] initWithData:data2]; 

     //Initialize the delegate. 
     SearchParameterDataParser *searchParameterDataParser = [[SearchParameterDataParser alloc] initSearchParameterDataParser]; 

     //Set delegate 
     [xmlParser5 setDelegate:searchParameterDataParser]; 

     //Start parsing the XML file. 
     @try { 
      // **the leakage line** 
      BOOL success1 = [xmlParser5 parse]; 


      if(success1) 
       NSLog(@"No Errors"); 
      else 
       NSLog(@"Error Error Error!!!"); 
     } 
     @catch (NSException * e) { 
      NSLog(@"Exception in parsing %@ %@",[e name], [e reason]); 
     } 
     //[xmlParser5 release]; 
     [searchParameterDataParser release]; 
     //[xmlParser5 release]; //leakage 
    } 

    [data2 release]; 

,這是我的語法分析器類:

#import "SearchParameterDataParser.h" 
#import "AppDelegate.h" 
#import "SearchClass.h" 

@implementation SearchParameterDataParser 
-(SearchParameterDataParser *)initSearchParameterDataParser{ 
    [super init]; 
    appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 
    return self; 
} 

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

    if([elementName isEqualToString:@"SearchClass"]) { 
     [appDelegate.tempArray release]; 
     appDelegate.tempArray = [[NSMutableArray alloc] init]; 
     appDelegate.aSearchClass = [[SearchClass alloc]init]; 
    } 


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

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 

    if(!currentElementValue){ 


     [currentElementValue release]; 
     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:@"SearchClass"]){ 
     [appDelegate.tempArray addObject:appDelegate.aSearchClass]; 

     return; 
    } 
    else 
     [appDelegate.aSearchClass setValue:currentElementValue forKey:elementName]; 




// [currentElementValue release]; 
    currentElementValue = nil; 
} 

- (void) dealloc { 
    [super dealloc];  
    [aSearchClass release]; 
    [currentElementValue release]; 
    //[self release]; 

} 
@end 

我在代碼中指定了泄漏線。

誰能告訴我哪裏出了問題,或者我該如何解決內存泄露???????

回答

3

這是相當混亂,作爲一個建議,清理了一點東西,嘗試將一些內存管理的東西存取方法 - 你的代碼與-release方法散落。即,

代替: -

if([elementName isEqualToString:@"SearchClass"]) { 
    [appDelegate.tempArray release]; 
    appDelegate.tempArray = [[NSMutableArray alloc] init]; 
} 

嘗試: -

if([elementName isEqualToString:@"SearchClass"]) { 

    appDelegate.tempArray = [NSMutableArray array]; 
} 

其中

的appDelegate有一個方法

- (void)setTempArray:(NSMutableArray *)value { 

    if(value!=tempArray){ 
     [tempArray release]; 
     tempArray = [value retain]; 
    } 
} 

,或者你可以使用一個@synthesized存取鱈魚的方法它自己。另外tempArArray是一個實例變量的可怕名稱。另外請注意,每當你創建一個新的時候,你都會釋放舊的tempArray - 最後一個實例什麼時候被清理?

這仍然不是很大作爲的appDelegate解析器類不應該直接訪問實例變量。 Vardiables tempArray和searchClass應該是私有的,但這不是關鍵問題,而是更多的設計問題。

url5在哪裏發佈?

這應該做什麼?

if(!currentElementValue){ 
    [currentElementValue release]; 
} 

release currentElementValue如果它不存在?

[data2 release]; 

您是否保留data2?

- (void) dealloc { 
[super dealloc];  
    [aSearchClass release]; 
    [currentElementValue release]; 
    //[self release]; 

} 

我以爲aSearchClass是appDelegate上的一個實例變量?

這聽起來像吹毛求疵,但它是非常容易,如果讓你的代碼清晰,你知道到底是怎麼回事追查泄漏。

+0

我知道tempArray不是一個好名字。但現在我已經接受了appDelegate,因爲我正在將所有數據加載到applicationDidDinishLaunching中,因此我在解析器類 中使用了該變量並且與[currentElementValue release]有關; 和[data2發佈],我已經發布了,因爲我對內存修復知之甚少,但無論我在哪裏通過儀器重定向,我都試圖通過釋放對象來解決泄漏問題,因爲我認爲它沒有發佈。 。如果有進一步的建議,歡迎 – harshalb 2009-11-04 12:15:52

1

您需要同時釋放url5xmlParser5,因爲您已使用alloc分配它們。

您還應該警惕在屬性上調用release,因爲當您設置新值之前,實例變量通常會釋放變量的前一個值時創建的標準設置器。

+0

youv在url5和xmlParse5上都是正確的,但是我上面沒有提到的另一個問題是每當我試圖釋放上述對象時,應用程序就會崩潰。請參閱我已發表評論xmlParser5的發佈 – harshalb 2009-11-04 12:19:27

+0

如果您在「xmlParse5」上調用「發佈」兩次,則應用程序將崩潰。你打電話給「解析」後應該調用它。 – 2009-11-04 13:08:50

+0

我只說過一次。我只是在嘗試之前或之後。不理會這兩個地方對於錯誤的印象感到抱歉。 – harshalb 2009-11-04 13:31:19

相關問題