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

HG'*_*G's 9 iphone memory-management objective-c

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

int count = [someObject retainCount];

for (int i = 0; i < count; i ++) 
{
[someObject release];
}
Run Code Online (Sandbox Code Playgroud)

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

Jha*_*iya 28

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

请阅读下面的Apple所说的内容retainCount.

重要说明:此方法在调试内存管理问题时通常没有价值.因为任何数量的框架对象可能保留了一个对象以保存对它的引用,而同时自动释放池可能在对象上保留任意数量的延迟版本,所以您不太可能从此获取有用信息方法.

要了解必须遵守的内存管理的基本规则,请阅读" 内存管理规则 ".要诊断内存管理问题,请使用合适的工具:

  • 更不用说*你自己的一个对象*也保留了对象的可能性.它的目标无关紧要; 如果你在物体仍然坚持的情况下将物体刺死,你将会在以后发生撞击. (3认同)

Eik*_*iko 14

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

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

这是内存管理编程指南.值得一读的不止一次.


NSG*_*God 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;
}
Run Code Online (Sandbox Code Playgroud)

这打印:

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

然后进入无限循环.

  • 在保留计数方面,"超出预期"并不意味着"不正确".它也不一定意味着你需要做任何事情来降低它 - 只要确保你自己的责任得到照顾,你自己的新/ alloc/retain/copy调用都与相应的(自动)版本平衡,并且一切都会好起来.对于你以外的物体,请记住 - 在NSVegas中会发生什么,留在NSVegas.:-) (2认同)

dea*_*rne 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];
Run Code Online (Sandbox Code Playgroud)

您的代码将强制myObject被取消分配.

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

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