【问题标题】:Best IOS Memory management @ Function Call With Returning allocated object最好的 IOS 内存管理@函数调用返回分配的对象
【发布时间】:2011-09-02 15:07:37
【问题描述】:

我有返回类型为(NSArray/NSData/NSString/NSDictionary 等)的函数。我也可以返回和使用,但是我的问题出现@释放对象。请指导我哪种方法是管理返回对象内存的最佳方法。如果有任何问题,请忽略并给出最佳解决方案

我参考过苹果内存管理指南

一)

-(NSData *)somefunction2
{  
   NSData *data=[[[NSData alloc]init]autorelease];  
    // fill stuff for nsdata
   return data;
}

-(void)somefunction
{    
NSData *data=[self somefunction2];    
// use data    
}

但大多数博客建议避免自动释放,所以我使用以下类型

B)

-(NSData *)somefunction2
{  
   NSData *data=[[NSData alloc]init];  
    // fill stuff for nsdata
   return data;
}

-(void)somefunction
{

NSData *data=[[self somefunction2] retain];

// use data

[data release];

}

C)

-(NSData *)somefunction2
{  
   NSData *data=[[[NSData alloc]init]autorelease];  
    // fill stuff for nsdata
   return data;
}

-(void)somefunction
{

NSData *data=[[self somefunction2] retain];

// use data

[data release];

}

编辑: 还有一件事。如果我尝试将相同的分配对象传递给某个函数调用参数或自定义委托对象,我必须在哪里释放????无论是在函数调用下方还是在函数 def 中保留然后释放。

NSData *data=[[NSData alloc]init];

[self somfunctioncall:data];

NSData *data=[[NSData alloc]init];

[delegate mydelegatefunction:data];


-(void)somfunctioncall:(NSdata *)data
{
NSData *newdata =[data retain];
//data use
[data release];}

提前致谢

【问题讨论】:

  • 注:前缀“get”仅用于间接返回值或对象的方法。

标签: ios memory-management memory-leaks


【解决方案1】:

最佳实践是,如果方法包含alloc, init, new or retain,则该方法返回retained 对象,如果不包含,则返回autoreleased 对象。我建议这样做:

-(NSString *)newData
{  
   NSData *data=[[NSData alloc]init];  
    // fill stuff for nsdata
   return data;
}

这样以后你就可以这样做了:

-(void)somefunction
{

NSData *data=[self newData];

// use data

[data release];

}

【讨论】:

  • :感谢您的回复。如何下线数据 NSData *data=[self getData];将获得所有权???。我认为我们需要保留所有权。
  • @Asta ni enohpi,您确实需要保留它以获得所有权,但是该方法正在为您执行此操作
  • 内存管理规则规定返回保留对象的方法“alloc”、“new”、“copy”或“mutableCopy”开头,而不是它们包含 他们。另外,方法名称是驼峰式的,这意味着“copyRightNotice”返回一个保留对象,而“copyrightNotice”不返回(后者以“copyright”开头,而前者以“copy”开头)。
  • @OScar 。我现在明白了,这种情况下该功能会做什么。还有一个疑问。请看我编辑的问题
  • 你违反了你所说的准则。您应该从方法中返回自动释放的对象。在这种情况下,您从一个不以 NARC 开头的方法返回一个拥有的对象,并且在someFunction 中,您正在释放一个您没有拥有所有权的对象。它之所以有效,是因为您知道您正在返回一个需要释放的对象 - 但您明确违反了准则。
【解决方案2】:

iOS 内存管理有时会令人困惑!首先我建议你总是在 XCode 中运行分析器,它会指出可能的内存泄漏,这非常有帮助!

由于 data 是一个局部变量,我相信默认情况下它是两个函数中的自动释放。

我看到 Oscar 刚刚为您提供了一些改进的代码,这也是我会投票支持的代码。

【讨论】:

  • 感谢 Alan Moore.. 如果我不使用 Autorelease,分析器会显示一些泄漏。
  • 在这种情况下,我会继续进行[数据发布]。就我个人而言,我根本不使用自动释放,我同意你读过的其他博客。
  • 感谢 +1 阿斯塔! Abizem——我喜欢 Oscar 比 A、B 或 C 更好。就个人而言,我更喜欢让 XCode 尽可能地进行内存管理,而忽略显式的保留和自动释放。然后我运行分析器来检查我可能遗漏的任何东西。最后,我在设备上使用 Leak Detector 工具运行了一个很好的长时间会话(模拟器会发现奇怪的泄漏),以防万一我忽略了其他任何事情。我发现这会导致 99.99% 的泄漏(假设您永远无法修复所有问题!)。
【解决方案3】:

我个人更喜欢第三种(C)方式。但是,在someFunction 中没有必要保留和释放data

【讨论】:

  • 如果你要使用它,你不应该保留它吗?在某些功能中使用它之前,池是否有可能会被耗尽?
  • 不需要保留它,除非他必须访问方法之外的对象。而且,据我所知,在该方法执行结束之前,自动释放池不可能耗尽。
【解决方案4】:

A 没问题。您返回创建一个对象并返回一个自动释放的对象。另一个函数使用这个对象,由于它不需要通过方法保持它,所以不需要保留或释放它。

在正确的地方使用自动释放没有没有错。名称中没有 new、alloc 的方法会返回自动释放的对象,因此可以在 getData 中返回一个自动释放的对象(这个名字很糟糕,但我们暂时不讨论)。

autorelease 在其他地方不鼓励,因为它会增加内存高水位线。当它被懒惰地使用时,它会被错误地使用——程序员不确定什么时候可以安全地释放拥有的对象,所以他们只是自动释放它们。

【讨论】:

  • 感谢您的明确回答并找到我的错误。抱歉命名为 getdata,现在我已经编辑了名称。我将经常使用上述概念。所以自动释放是否会影响我的代码性能。请指导我。说真的,我读了很多博客。所有的人都使用不同的风格。
  • 你的最后一句话突然让我明白了为什么这么多人建议避免autorelease。嗯。不过谢谢。 :)
【解决方案5】:

“A”是正确的。在 iOS 中避免使用autorelease 的建议是在在单个方法中,而不是在方法之间管理对象的生命周期方面的性能增强。

【讨论】:

    【解决方案6】:

    不要回避autorelease

    如果博客告诉您避免使用autorelease,他们就是在给您不好的建议。这是过早的性能优化。使用autorelease 可以简化代码并且几乎不会影响性能。并且它确实影响性能的几次,很容易修复。

    “A”是正确的。

    "B" 不正确,因为它不遵循 Objective-C 命名约定。这很重要。很多。当您学习 Objective-C 约定时,您会发现很难集成此代码。编译器可能会给你不好的警告。并且下一个版本的 llvm 将具有自动引用计数,这意味着您可以依靠编译器为您的 Objective-C 对象编写内存管理代码。它是根据约定来做的,所以它会失败。

    “C”也是正确的,但在这种情况下不必要地复杂。如果您在处理数据时可能会耗尽自动释放池,那么这将是正确的代码。

    【讨论】:

    • 另外 - 不要依赖 ARC 来解决所有内存管理问题。它仅适用于 Objective-C 对象,因此您仍然需要自己管理从 C API(CoreGraphics、CoreFoundation、GCD 等)返回的对象。
    • 好点。为此稍微调整了我的答案。我不解释 C API,但现在我正确地将 ARC 限制为 Objective-C 对象。
    猜你喜欢
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 2020-09-21
    • 1970-01-01
    • 2012-02-28
    相关资源
    最近更新 更多