Ios OBJ-C:如何释放从方法返回的对象?

Ios OBJ-C:如何释放从方法返回的对象?,ios,objective-c,memory-leaks,Ios,Objective C,Memory Leaks,我对从方法返回的对象的内存警告感到困惑。 这是我的密码 -(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=@"O

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

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

这是我的两种方法。 1.-(无效)returnHeaderView。 2.-(UILabel*)返回标签

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

但它给出了一个记忆警告( 正确减少调用方此时不拥有的对象的引用计数)

任何人都可以告诉我这段代码有什么问题。 以及如何释放方法返回的对象


谢谢。

在我看来,您的
returnLabel
方法返回的对象的保留计数为1,而不是编译器建议的零。我认为您可能只需要更改方法名,就可以向编译器提示返回对象的所有权。尝试将
returnLabel
更改为
createReturnLabel
。然后该方法将符合。

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

-(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。

在您的
returnHeaderView
中,您实际上没有保留标签中的
,因此您不拥有它,也不应该在那里释放它(警告“此时调用方不拥有的对象的引用计数减少错误”)

最好的选择是自动释放返回的标签:
return[label autorelease]
并让它继续运行,直到周围的自动释放池排空。注意,这也意味着删除
[fromLabel release]
returnHeaderView
方法调用


如果这听起来很复杂,请按照实际建议使用ARC。

请进行微小更改并删除泄漏,同时自动恢复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];
}

你们可以参考,苹果的是所有Objective-C程序员的必读书目。它完全回答了这个问题和许多其他重要的内存管理问题。如果他将自动释放添加到
returnLabel
,他甚至不需要保留和释放。如果他这样做,他应该只添加自动释放,以便returnLabel返回一个自动释放的对象,然后在
returnHeaderView
@AaronGolden中不保留或释放
fromLabel
:他正在对返回的
UILabel
执行一些任务。因此,如果在return语句之后立即排空
autorelease池
,则可能会发生崩溃。但是,在OP发布的代码中返回
returnLabel
之后,肯定不会立即排空autorelease池@是的,没关系。但这不是推荐的方法。始终保留返回的自动释放对象(获取所有权)。Apple文档建议采用这种方法。fromLabel由
[self.headerView addSubview:fromLabel]
中的
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];
}