3

我对从方法返回的对象的内存警告感到困惑。这是我的代码。

-(void)returnHeaderView
{
  self.headerView=[[UIView alloc]init];
  headerView.frame=CGRectMake(0, 0, 955, 45);


  UILabel *fromLabel=[self returnLabel];
  fromLabel.frame=CGRectMake(400, 5, 200, 44);
  fromLabel.text=@"Open Time";
  [headerView addSubview:fromLabel];
  [fromLabel release];(in correct decrement of the reference count of an object that is not owned at this point by the caller)

 [self.headerView addSubview:fromLabel];
 [self.view addSubview:self.headerView];
 [self.headerView release];

}

-(UILabel *)returnLabel
{
UILabel *label= [[UILabel alloc] init] ;
label.textColor = [UIColor blackColor];
label.font = FONT_TITLE;
label.numberOfLines=1;
label.textAlignment=UITextAlignmentLeft;
label.lineBreakMode=UILineBreakModeWordWrap;
label.backgroundColor=[UIColor clearColor];

return label;

}

这是我的两种方法。1.-(void)returnHeaderView。2.-(UILabel *)returnLabel。

-returnLabel 是返回标签,方法返回的 UILabel 对象的引用传递给 returnHeaderView 方法的 fromLabel UILabel 对象。然后我释放 fromLabel 对象。

但它给出了内存警告(正确减少调用者此时不拥有的对象的引用计数)。

所以有人建议我这段代码有什么问题。以及如何释放方法返回的对象。图片来自我的代码,它描述了分析程序生成的内存警告。

谢谢。

4

4 回答 4

3

在您的情况下,returnHeaderView您实际上并不保留fromLabel,因此您不拥有它,也不应该在那里释放它(警告“不正确地减少调用者此时不拥有的对象的引用计数”)。

最好的选择是自动释放返回的标签:return [label autorelease];让它一直存在,直到周围的自动释放池被耗尽。请注意,这也意味着[fromLabel release];从您的方法中删除调用returnHeaderView

如果这听起来很复杂,请按照实际推荐的方式使用 ARC。

于 2013-04-04T06:59:21.473 回答
2

请进行小的更改和泄漏删除,并自动释放 self.headerView 以删除其他内存泄漏警告:

-(void)returnHeaderView
{
  self.headerView=[[[UIView alloc]init] autorelease];
  headerView.frame=CGRectMake(0, 0, 955, 45);

  UILabel *fromLabel = [[self returnLabel] retain];
  fromLabel.frame    = CGRectMake(400, 5, 200, 44);
  fromLabel.text     = @"Open Time";
  [headerView addSubview:fromLabel];
  [self.headerView addSubview:fromLabel];
  [self.view addSubview:self.headerView];
  //[self.headerView release];
}

-(UILabel *)returnLabel
{
  UILabel *label= [[UILabel alloc] init] ;
  label.textColor = [UIColor blackColor];
  label.font = FONT_TITLE;
  label.numberOfLines=1;
  label.textAlignment=UITextAlignmentLeft;
  label.lineBreakMode=UILineBreakModeWordWrap;
  label.backgroundColor=[UIColor clearColor];
  return [label autorelease];
}
于 2013-04-04T07:04:23.153 回答
1

在我看来,您的returnLabel方法返回一个保留计数为 1 的对象,而不是编译器建议的零。我认为您可能只需要更改方法名称即可向编译器提示返回对象的所有权。尝试更改returnLabelcreateReturnLabel. 然后该方法将符合复制/创建命名约定

于 2013-04-04T05:58:41.650 回答
1

您可以通过更改代码来避免泄漏,例如:

-(void)returnHeaderView
{
  self.headerView=[[UIView alloc]init];
  headerView.frame=CGRectMake(0, 0, 955, 45);


  UILabel *fromLabel = [[self returnLabel] retain];
  fromLabel.frame    = CGRectMake(400, 5, 200, 44);
  fromLabel.text     = @"Open Time";
  [headerView addSubview:fromLabel];
  [self.headerView addSubview:fromLabel];
  [self.view addSubview:self.headerView];

  [fromLabel release];
  [self.headerView release];

}

-(UILabel *)returnLabel
{
UILabel *label= [[UILabel alloc] init] ;
label.textColor = [UIColor blackColor];
label.font = FONT_TITLE;
label.numberOfLines=1;
label.textAlignment=UITextAlignmentLeft;
label.lineBreakMode=UILineBreakModeWordWrap;
label.backgroundColor=[UIColor clearColor];

return [label autorelease];

}

建议:避免此类泄漏的最佳方法是使用 ARC。

于 2013-04-04T06:26:45.420 回答