【问题标题】:Hunting down Leaks寻找泄漏
【发布时间】:2009-08-18 18:59:18
【问题描述】:

我仍在处理我的泄漏问题,我不知道如何解决这个问题我在每个 arrayTmp addObject 行都有泄漏

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


[arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"1", @"value", @"Value 1", @"name", nil]];
[arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"2", @"value", @"Value 2", @"name", nil]];
[arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"3", @"value", @"Value 3", @"name", nil]];
[arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"4", @"value", @"Value 4", @"name", nil]];
//add arrayTmp to an object to use later
[arrayTmp release];
arrayTmp=nil;

arrayTmp= [[NSMutableArray alloc] init];

[arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"1", @"value", @"other value 1", @"name", nil]];
[arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"2", @"value", @"other value 2", @"name", nil]];
//add arrayTmp to an object to use later
[arrayTmp release];
arrayTmp=nil;
...

这里是我的过滤器类的代码

@implementation Filter

@synthesize label;
@synthesize valueIndex;
@synthesize listValue;
@synthesize webServiceFieldName;

-(id) initWithLabel:(NSString *)plabel AndValue:(int)pvalueIndex AndListValue:(NSMutableArray *)plistValue AndWebServiceFieldName:(NSString *)pwebServiceFieldName {

self = [super init];

if (self != nil) {
    self.label = plabel;
    self.valueIndex = pvalueIndex;
    self.listValue = plistValue;
    self.webServiceFieldName = pwebServiceFieldName;

}
return self;
}

@end

【问题讨论】:

  • 我没有看到任何泄漏。你在用什么来告诉你有什么?
  • 我使用xCode泄漏性能工具第二次调用此代码时出现泄漏
  • 如何将arrayTmp添加到对象中以备后用?那里是否有实际代码,如果有,它是什么?那可能是泄漏...另外,您不需要设置为零。毫无意义。
  • 例如,如果您有后续的 [arrayTmp length] 调用,将 var 设置为 nil 可能会防止您崩溃。如果没有更广泛的背景,我不会说它毫无意义。
  • 我做了类似 filterTmp1 = [[Filter alloc] initWithLabel:@"Filter 1" AndValue:0 AndListValue:arrayTmp AndWebServiceFieldName:@"filter1"];

标签: objective-c arrays memory-leaks nsdictionary


【解决方案1】:
//add arrayTmp to an object to use later

这意味着您将 arrayTmp 推入一个对象并保留它。被剪断的代码在其他方面都很好,但我敢打赌泄漏存在于该方法中。

发布您的方法的代码(顺便说一句,如果您要遵循 Obj-C 的命名约定,该方法实际上应该是 -initWithLabel:value:listValue:webServiceFieldName:),它存储了 arrayTmp 和释放它的代码。

在 Instruments 中,您应该能够使用 Object Alloc 工具查看数组实例。单击任何一个都应为您提供该地址的分配/保留/释放/解除分配事件列表。通过展开窗口右侧的“更多信息”窗格(通过底部的小按钮),您可以查看任何给定事件的堆栈跟踪。

从下面的代码中,您的初始化程序设置 ivars,包括传入的 tmpArray:

    self.label = plabel;
    self.valueIndex = pvalueIndex;
    self.listValue = plistValue;
    self.webServiceFieldName = pwebServiceFieldName;

但是,我没有看到 -dealloc 方法。

假设您的属性是用retain 或copy 声明的,您的dealloc 应该如下所示:

- (void) dealloc
{
    [label release];
    [listValue release];
    [webServiceFileName release];
    [super dealloc];
}

【讨论】:

    【解决方案2】:

    您必须确保在释放此对象时释放合成的成员变量——它不会自动为您完成。例如:

    - (void)dealloc
    {
        [label release];
        [listValue release];
        [webServiceFieldName release];
    
        [super dealloc];
    }
    

    【讨论】:

    • 你忘记了 [super dealloc];最后。
    【解决方案3】:

    在上面的代码中,分配SearchCriteria 并调用initSearchFilters 的行会将结果的retainCount 设置为1。然后,当您通过addObject 将该对象添加到self.searchFilters 时,retainCount 即为撞到 2。此时您需要调用 [searchCriteriaTmp release] 将 retainCount 设置回 1。当 self.searchFilters 被销毁时,retainCount 将变为 0,并且对象将被释放。如果没有对 release 的额外调用,retainCount 将始终为 1,并且对象永远不会释放,从而导致泄漏。

    【讨论】:

      【解决方案4】:

      好的,我进行了这些更改,但这些行仍有十几个漏洞 这是我的代码示例

      -(id)initSearchFilters{
          self = [super init];
      
      
          if ( self ) {
      
          //init the search filters array
          self.searchFilters = [[NSMutableArray alloc] init];
          SearchCriteria *searchCriteriaTmp;
          Filter *filterTmp1;
          Filter *filterTmp2;
          NSMutableArray *arrayTmp= [[NSMutableArray alloc] init];
      
          //Price Range
          arrayTmp = [[NSMutableArray alloc] init];
      
          [arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"any", @"value", @"any", @"name", nil]];
          [arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"100", @"value", @"$100", @"name", nil]];
          [arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"200", @"value", @"$200", @"name", nil]];
          [arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"300", @"value", @"$300", @"name", nil]];
          [arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"400", @"value", @"$400", @"name", nil]];
          [arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"500", @"value", @"$500", @"name", nil]];
      
      
          filterTmp1 = [[Filter alloc] initWithLabel:@"Minimum Price" AndValue:0 AndListValue:arrayTmp AndWebServiceFieldName:@"price_min"];
          filterTmp2 = [[Filter alloc] initWithLabel:@"Maximum Price" AndValue:0 AndListValue:arrayTmp AndWebServiceFieldName:@"price_max"];
          searchCriteriaTmp = [[SearchCriteria alloc] initWithFilter1:filterTmp1 AndFilter2:filterTmp2 AndLabelSearchCriteria:@"Price Range" AndEnabled:NO];
          [self.searchFilters addObject:searchCriteriaTmp];
          [arrayTmp release];
          arrayTmp=nil;
          [filterTmp1 release];
          filterTmp1=nil;
          [filterTmp2 release];
          filterTmp2=nil;
          [searchCriteriaTmp release];
          searchCriteriaTmp=nil;
      
          //Item
          arrayTmp = [[NSMutableArray alloc] init];
      
          [arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"1", @"value", @"item 1", @"name", nil]];
          [arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"2", @"value", @"item 2", @"name", nil]];
          [arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"3", @"value", @"item 3", @"name", nil]];
          [arrayTmp addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"4", @"value", @"item 4", @"name", nil]];
      
          filterTmp1 = [[Filter alloc] initWithLabel:@"Item" AndValue:0 AndListValue:arrayTmp AndWebServiceFieldName:@"item"];
          searchCriteriaTmp = [[SearchCriteria alloc] initWithFilter1:filterTmp1 AndFilter2:nil AndLabelSearchCriteria:@"Item" AndEnabled:NO];
          [self.searchFilters addObject:searchCriteriaTmp];
          [arrayTmp release];
          arrayTmp=nil;
          [filterTmp1 release];
          filterTmp1=nil;
          [searchCriteriaTmp release];
          searchCriteriaTmp=nil;
          }
          return self;
      }
      

      还有我的搜索条件类

      -(id)initWithFilter1:(Filter *)pFilter1 AndFilter2:(Filter *)pFilter2 AndLabelSearchCriteria:(NSString *)pLabelSearchCriteria AndEnabled:(BOOL)pEnabled{
      
      self = [super init];
      
      if (self != nil) {
          self.filter1 = pFilter1;
          self.filter2 = pFilter2;
          self.labelSearchCriteria = pLabelSearchCriteria;
          self.enabled =pEnabled;
      }
      return self;
      }
      
      - (void)dealloc
      {
      [filter1 release];
      [filter2 release];
      [labelSearchCriteria release];
      [super dealloc];
      }
      

      【讨论】:

      • 我多次调用 initSearchFilters 所以我认为这是由于 self.searchFilters = [[NSMutableArray alloc] init];但是我可以在哪里放置这条线,以便只调用一次呢?
      • 好的,我解决了,这是由于对 initSearchFilters 的多次调用
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-11
      • 2011-02-25
      • 2011-05-11
      • 1970-01-01
      • 2012-06-16
      • 1970-01-01
      • 2011-03-17
      相关资源
      最近更新 更多