【问题标题】:Can anyone identify the leakage , help?任何人都可以识别泄漏,帮助?
【发布时间】:2009-11-04 10:52:20
【问题描述】:

我已经开发了我的 iPhone 应用程序,现在我正在使用仪器对其进行测试以发现内存泄漏。

我有我的 appDelegate 类,我在其中从 Web 服务获取数据,然后对其进行解析,然后将其存储在一个数组中..

这是我的 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

我已经在代码中指定了泄漏线。

谁能告诉我出了什么问题或者我该如何解决内存泄漏???????

【问题讨论】:

    标签: iphone memory-leaks instruments


    【解决方案1】:

    这很混乱,建议您稍微清理一下,尝试将一些内存管理内容移至访问器方法 - 您的代码中充斥着 -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 访问器方法来节省自己的编码。顺便说一句,tempArray 是一个实例变量的可怕名称。另请注意,每次创建新的 tempArray 时都会释放旧的 tempArray - 最后一个实例何时被清理?

    这仍然不是很好,因为您的解析器类不应该直接访问 appDelegate 中的实例变量。变量 tempArray 和 searchClass 应该是私有的,但这不是重点,更多的是设计问题。

    url5在哪里发布?

    这是做什么的?

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

    如果 currentElementValue 不存在则释放它?

    [data2 release];
    

    你保留了data2吗?

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

    我认为 aSearchClass 是 appDelegate 上的实例变量?

    这听起来像是在吹毛求疵,但如果让你的代码清晰并且你确切地知道发生了什么,那么追踪泄漏就会容易得多。

    【讨论】:

    • 我知道 tempArray 不是个好名字。但是现在我已经接受了 appDelegate,因为我正在将所有数据加载到 applicationDidDinishLaunching 中,所以我在解析器类中使用该变量并与 [currentElementValue release];和 [data2 release] ,我已经发布了,因为我对内存修复知之甚少,但是无论我在哪里被仪器重定向,我都试图通过释放对象来解决泄漏,因为我认为它没有被释放..如果欢迎您提出进一步的建议
    【解决方案2】:

    您需要同时释放url5xmlParser5,因为您已经使用alloc 分配了它们。

    您还应该警惕在属性上调用release,因为当您@synthesize 实例变量时创建的标准设置器通常会在设置新值之前释放该变量的先前值。

    【讨论】:

    • youv 在 url5 和 xmlParse5 上都是正确的,但我上面没有提到的另一个问题是,每当我尝试释放上述对象时,应用程序就会崩溃。见我已经评论了 xmlParser5 的发布
    • 如果你在 "xmlParse5" 上调用 "release" 两次,你的应用程序将会崩溃。你应该在调用“parse”之后调用它一次。
    • 我只调用过一次。我只是在之前或之后尝试。忽略这两个地方对不起印象不好..
    猜你喜欢
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-12
    • 2021-12-13
    • 2020-12-01
    相关资源
    最近更新 更多