使用 NSMutableArray 时内存泄漏

Posted

技术标签:

【中文标题】使用 NSMutableArray 时内存泄漏【英文标题】:Memory leaks while using NSMutableArray 【发布时间】:2011-08-26 02:51:28 【问题描述】:

大家好,有人可以建议如何解决下面代码中的内存泄漏

我已经尝试了几乎所有我能想到的 release 和 autorelease 组合,但每次应用程序崩溃或泄漏仍然存在时

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component

//get refereance to the textfield
UITextField *currentTextField = (UITextField*)[self.view viewWithTag:200];

//check which picker
if(pickerView.tag ==1)
   
    // Only calls the following code if component "0" has changed.
    if (component == 0) 

        // Sets the global integer "component0Row" to the currently selected row of component "0"
        component0Row  = row;

        // Loads the new values for the selector into a new array in order to reload the data.
    newValues = [[NSMutableArray alloc] initWithArray:[pickerData objectForKey:[selectorKeys objectAtIndex:component0Row]]];
        currentValues = newValues;


        // Reloads the data of component "1".
        [pickerView reloadComponent:1];


    

    //run the selector logic
    [self textFieldDidEndEditing:currentTextField];


希望有人可以建议

非常感谢

【问题讨论】:

【参考方案1】:

你的问题是这两行:

newValues = [[NSMutableArray alloc] initWithArray:[pickerData objectForKey:[selectorKeys objectAtIndex:component0Row]]];
currentValues = newValues;

第一行分配了一个新的 NSMutableArray 实例。第二行将指针从newValues 复制到currentValues覆盖currentValues 中的指针值。无论currentValues 指向什么都丢失了。这就是泄漏。

你可以这样修复它:

newValues = [[NSMutableArray alloc] init...
[currentValues release];
currentValues = newValues;

这样,currentValues 指向的任何内容都会在您无法访问之前减少其引用计数。

您还可以通过将 currentValues 设为 Objective-C 属性并通过self.currentValues[self setCurrentValues:] 使用访问器方法来解决该问题;这些方法将为您处理保留/释放。

【讨论】:

嗨 Benzado 感谢您的建议,但我之前已经厌倦了这个版本,现在又一次,当我滚动选择器时,应用程序因 exc-bad-access 而崩溃,这让我现在发疯了 您询问了泄漏。这些答案将堵住你的泄漏。崩溃是另一个问题。谷歌获取说明并在objc_exception_throw 上放置一个断点,这样你就可以找出坏指针是什么。如果您无法弄清楚 ,请提出一个新问题。 如果我采用您建议的代码来堵塞泄漏,就会发生崩溃。堵塞的泄漏可能会在代码的另一部分造成崩溃吗?我不太明白这个所以希望你能详细解释一下谢谢【参考方案2】:

你的 NSMutableArray 分配永远不会被释放。

newValues = [[NSMutableArray alloc] initWithArray:[pickerData objectForKey:[selectorKeys objectAtIndex:component0Row]]];

您应该自动释放它,或者稍后在您知道不再需要它时释放它。

【讨论】:

嗨,Alex,我已经尝试过自动释放,但是我在 dealloc 中释放了应用程序崩溃,但这并不能阻止仪器在之后发现泄漏【参考方案3】:

不确定您是如何定义 currentValues 的,但这应该可以在没有泄漏的情况下工作:

在您的 .h 文件中:

@property (nonatomic, retain) NSArray * currentValues;

在您的 .m 文件中:

@synthesize currentValues;

self.currentValues = newValues;

【讨论】:

喜感 currentValues 是在 viewdidload 中分配的,像这样 currentValues = [[NSMutableArray alloc] initWithArray:[pickerData objectForKey:[selectorKeys objectAtIndex:component0Row]]]; @superllanboy - currentValues 是您的视图的属性还是您在函数中声明的变量?如果是后者,那么您发现了泄漏。 喜感 currentvalues 是一个属性 好的,那么您的泄漏很可能发生,因为您将当前值用作 ivar(每当您替换它的值时,您都会泄漏原来的旧对象)。不要做currentValue = someobj,而是做self.currentValue = someobj

以上是关于使用 NSMutableArray 时内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

NSMutableArray 内存泄漏问题

NSMutableArray 和属性泄漏内存

iPhone SDK 中的 NSMutableArray、NSArray、NSString 内存泄漏

如何在不造成内存泄漏的情况下清除自定义对象的 NSMutableArray?

ARC 内存泄漏

initWithFrame 中的内存泄漏