任何人都可以识别泄漏,帮忙吗?

发布于 2024-08-09 17:54:05 字数 5666 浏览 7 评论 0原文

我已经开发了我的 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

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

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

I have developed my iPhone application and now I am testing it with instruments to find memory leakages .

I have my appDelegate class in which I am fetching data from web service and then parse it then store it in an array..

Here is my applicationDidFinishLaunching method :

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];

and this is my parser class :

#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

I have specified the leakage line in the code .

Can anyone tell me what is going wrong or how can I solve the memory leakage ???????

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

草莓酥 2024-08-16 17:54:05

这非常混乱,作为清理一下的建议,尝试将一些内存管理内容移至访问器方法 - 您的代码中充斥着 -release 方法。即,

而不是:-

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

try:-

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 上的实例变量?

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

This is pretty messy, as a suggestion to clean things up a bit, try moving some memory management stuff to accessor methods - your code is littered with -release methods. ie,

instead of:-

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

try:-

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

    appDelegate.tempArray = [NSMutableArray array];
}

where

appDelegate has a method

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

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

or you can use a @synthesized accessor method to save coding it yourself. As an aside tempArray is a terrible name for an instance variable. Also note that you are releasing the old tempArray each time you make a new one - when does the last instance get cleaned up?

This is still not great as your parser class should not access directly the instance variables in appDelegate. Vardiables tempArray and searchClass should be private, but that is off the point and more of a design issue.

Where does url5 get released?

What is this supposed to do?

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

release currentElementValue if it doesn't exist?

[data2 release];

Did you retain data2?

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

}

i thought aSearchClass was an instance variable on appDelegate?

This might sound like nitpicking but it is much easier to track down leaks if make your code clear and you know exactly what is going on.

一桥轻雨一伞开 2024-08-16 17:54:05

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

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

You need to release both url5 and xmlParser5, since you've allocated them using alloc.

You should also be wary of calling release on properties, since the standard setters created when you @synthesize an instance variable typically release the previous value of the variable before setting the new value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文