在使用Instruments进行性能分析时,main.m文件中存在内存泄露问题?

3
在我的一个应用程序中,我在UIKit、UIFoundation和QuartzCore中出现了内存泄漏。当我查看调用树时,它显示在main.m中有泄漏。我真的不知道为什么会发生这种情况。您可以在下面看到内存泄漏的截图。enter image description here

在调用树中

enter image description here

如何解决这些泄漏?

内存泄漏代码

- (void) showCustomPrices
{

int priceValue = 0;
NSArray* priceSplitValue = [btnpriceButton.titleLabel.text componentsSeparatedByString: @"."];
NSString* priceFinal = [priceSplitValue objectAtIndex:0];

for(int i=0;i<[priceArray count];i++)
{ 
    if([[priceArray objectAtIndex:i] isEqualToString:priceFinal]){
        priceValue = i; 
    }
}


    //Assign the cocktail to picker view
    priceActionsheet = [[UIActionSheet alloc] initWithTitle:nil
                                              delegate:self
                                     cancelButtonTitle:nil
                                destructiveButtonTitle:nil
                                     otherButtonTitles:nil];//as we want to display a subview we won't be using the default buttons but rather we're need to create a toolbar to display the buttons on

    [priceActionsheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];

    CGRect pickerFrame = CGRectMake(0, 40, 0, 0);

    pricePickerview = [[UIPickerView alloc] initWithFrame:pickerFrame];
    pricePickerview.showsSelectionIndicator = YES;
    pricePickerview.dataSource = self;
    pricePickerview.delegate = self;


    [priceActionsheet addSubview:pricePickerview];
    //[pickerView release];

    priceToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 485, 44)];
    priceToolbar.barStyle = UIBarStyleBlackTranslucent;
    [priceToolbar sizeToFit];

    NSMutableArray *barItems = [[NSMutableArray alloc] init];

    UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
    [barItems addObject:flexSpace];

    UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneButtonPressed:)];
    [barItems addObject:doneBtn];

    UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelButtonPressed:)];
    [barItems addObject:cancelBtn];

    [pricePickerview selectRow:priceValue inComponent:0 animated:YES];//Memory leaks shows 100% here

    [priceToolbar setItems:barItems animated:YES];

    [priceActionsheet addSubview:priceToolbar];

    [priceActionsheet addSubview:pricePickerview];

    [priceActionsheet showInView:self.view];  

    [priceActionsheet setBounds:CGRectMake(0, 0, 485, 320)];

非常感谢您的帮助。


如果您在第一张图中单击对象地址旁边的小箭头,它将显示保留/释放历史记录。我发现这是关于对象被保留的最好线索。 - Phillip Mills
@PhillipMills 我编辑了我的问题,请看一下。谢谢。 - vinothp
在顶部栏中有3个“视图”按钮。选择最右边的一个,查看堆栈跟踪,并查看是否有来自您应用程序代码的方法调用。 - Or Arbel
@OrArbel,我能看到堆栈跟踪,但找不到任何来自应用程序代码的方法调用...我更新了我的问题,请查看一下。 - vinothp
为什么不尝试使用属性呢?比如使用self.pricePickerview,看看会发生什么。 - Abdullah Umer
显示剩余3条评论
4个回答

1

最终,我通过将选择器视图的分配/初始化部分从方法showCustomePrices移动到viewwillAppear中解决了我的问题。这样做非常好,没有任何内存泄漏。

之前发生的情况是每当我点击按钮时,它都会弹出带有内存分配的pickerview。这就是为什么会发生内存泄漏的原因。

现在,在移动到viewwillAppear后,它只在视图加载时第一次分配。然后可以访问选择器视图而不进行任何内存分配。因此,内存泄漏已经被消除。


很奇怪。我在我的项目中使用了UIPickerView,并且每当按下UIButton时,我都会进行分配+初始化。但是我没有泄漏。 - Abdullah Umer
是的,这真的很奇怪。我在不同的项目中使用了相同的代码,它有效果,但在这个项目中却不行。 - vinothp
如果一次性分配适合您,我认为最好将其放在viewDidLoad()中,而不是viewWillAppear()中。 - Abdullah Umer
可以,但是根据我的项目要求,每当设置发生更改时,我都会更改pickerview的数组。因此,在viewwillappear中它可以完美地工作,而在viewdidload中则不行。 - vinothp

1

如果您的项目是非ARC的,可能是因为您在子类化基础类时遗漏了[super dealloc];。我曾经在一个NSObject的子类中遇到过同样的问题。我忘记写[super dealloc];,导致出现了类似的泄漏。


谢谢你的回答。我在ARC中创建了项目,并从非ARC项目中复制了一些内容。我不确定如何处理你的回答。 - vinothp
你确定在项目的非ARC部分没有任何泄漏吗? - Abdullah Umer
我希望如此,但如何具体检查呢? - vinothp
我有一个静态的分组表视图控制器。我注释了cellforrowatindexpath方法,因为它对于静态表格来说是不需要的。但是泄漏看起来指向了这个方法。 - vinothp
我现在真的不记得了。那是一年前的事了。当时我几乎和你一样相信泄漏是来自Foundation库,所以我忽略了它。但是几天后,当我浏览我的旧代码时,我看到一个没有 [super dealloc]; 的类:/ 然后Bingo!... - Abdullah Umer
我更新了我的代码,但存在内存泄漏问题,如何解决?谢谢。 - vinothp

0
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;

在你的 main.m 中尝试这个


-1
int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, @"yourAppName", nil);
    [pool release];
    return retVal;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接