这是释放记忆的好方法吗?

时间:2011-06-30 12:18:51

标签: iphone objective-c memory-management

我已经在iPhone上进行了一段时间的编程,并且在内存管理方面遇到了不好的经历。我想知道以下方式是否是释放内存的好方法。

int count = [someObject retainCount];

for (int i = 0; i < count; i ++) 
{
[someObject release];
}

这种方法在我面临的一些情况下(特别是UIWebViews)是一种绝望的行为。变量的retainCount减少到零,这将释放它使用的内存。该方法有点脏,但是它有任何瓶颈吗?

6 个答案:

答案 0 :(得分:28)

您不应该依赖retainCount,因为有可能通过iOS框架保留对象,

请阅读Apple retainCount所说的内容。

  

重要提示:此方法通常是   调试内存没有价值   管理问题。因为任何数字   框架对象可能已保留   一个对象,以保持参考   在它同时,同时   自动释放池可能持有任何   一个延迟发布的数量   对象,你不太可能   可以从中获得有用的信息   方法

要了解您必须遵守的内存管理的基本规则,请阅读“Memory Management Rules”。要诊断内存管理问题,请使用合适的工具:

答案 1 :(得分:14)

此代码绝对是禁止。它只是隐藏了你的编程错误 - 而且它的表现非常糟糕。

请学习正确的内存管理。没有替代品。

这是memory management programming guide。不止一次值得阅读。

答案 2 :(得分:7)

正如其他人所说,-retainCount几乎没用。当您刚开始使用Objective-C中的内存管理/引用计数时,有时可能会尝试使用 - retainCount来帮助理解引用计数的工作方式,但实际上,它可能(看似)最让人困惑的。

您发布的代码本身就具有潜在的危险性,具体取决于您使用someObject的周围环境。当应用于您不期望的其他情况时,它也可能是危险的。使用NSString编译器指令创建的常量@"a string":创建这些字符串并将其设计为永不释放。因此,在以下示例中应用您的代码将导致无限循环:

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSString *string = @"theString";

    NSLog(@"retainCount == %lu", (unsigned long)[string retainCount]);

    for (NSUInteger i = 0; i < [string retainCount]; i++) {
        [string release];
    }

    [pool drain];
    return 0;
}

打印:

2011-06-30 08:40:16.287 retainCount[35505:a0f] retainCount == 1152921504606846975

然后进入无限循环。

答案 3 :(得分:6)

我不能说得太厉害了!

以您的代码实例为例:

// Create an autoreleased object
MyObject *myObject = [[[MyObject alloc] init] autorelease];

// Run your code to make it dealloc itself
int count = [myObject retainCount];
for (int i = 0; i < count; i ++)
    [myObject release];

您的代码会强制myObject被解除分配。

但是,myObject也已被放入自动释放池中 - 一旦池开始释放它的对象,您的应用就会崩溃,因为myObject不再存在!

规则很简单:每次使用init,new或copy时都要调用release。否则,这不是你的问题。

答案 4 :(得分:3)

您不应该依赖retainCount的值。您应该按照调用alloccopy的频率发布。

修改:以及newretain

答案 5 :(得分:3)