【问题标题】:Beginner memory management初学者内存管理
【发布时间】:2011-11-20 02:02:15
【问题描述】:

如果我想在我的代码中进行良好的内存管理,我需要知道对象的retaincount 是否应该始终为0。我从一本书中得到了以下代码。并且有一个声明 NSLog 称为 after release = 2,所以我应该再释放它 2 次以使 retaincount 为 0 吗?

#import <Foundation/NSObject.h>
    #import <Foundation/NSAutoreleasePool.h>
   #import <Foundation/NSString.h>
 #import <Foundation/NSArray.h>
 #import <Foundation/NSValue.h>
 int main (int argc, char *argv[])
 {
 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 NSNumber *myInt = [NSNumber numberWithInteger: 100];
 NSNumber *myInt2;
 NSMutableArray *myArr = [NSMutableArray array];
 NSLog (@”myInt retain count = %lx”,
 (unsigned long) [myInt retainCount]);
 [myArr addObject: myInt];
 NSLog (@”after adding to array = %lx”,
 (unsigned long) [myInt retainCount]);
 myInt2 = myInt;
 NSLog (@”after asssignment to myInt2 = %lx”,
 (unsigned long) [myInt retainCount]);
 [myInt retain];
 NSLog (@”myInt after retain = %lx”,
 (unsigned long) [myInt retainCount]);


 NSLog (@”myInt2 after retain = %lx”,
 (unsigned long) [myInt2 retainCount]);
 [myInt release];
 NSLog (@”after release = %lx”,
 (unsigned long) [myInt retainCount]);
 [myArr removeObjectAtIndex: 0];
 NSLog (@”after removal from array = %lx”,
 (unsigned long) [myInt retainCount]);
 [pool drain];
 return 0;
 }

程序输出

myInt 保留计数 = 1
添加到数组后 = 2
分配给 myInt2 = 2
保留后的 myInt = 3
保留后的 myInt2 = 3
发布后 = 2
从数组中删除后 = 1

更新

The following code was taken from the Apples memory management document。他们保留了一个 NSNumber 对象并且它从未被释放,这样可以吗?

- (void)setCount:(NSNumber *)newCount {
[newCount retain];
[_count release];
// Make the new assignment.
_count = newCount;
}

【问题讨论】:

  • 请注意,myInt 和 myInt2 的保留计数是相同的,因为保留计数适用于对象,而不是指针变量,并且这两个指针变量都指向同一个对象。
  • 请注意,在您的示例中,“释放后”的保留计数为 2,因为数组“拥有”一个计数,自动释放对象“拥有”一个计数。
  • 请在 Stackoverflow 中搜索 retainCount,看看声誉超过 5000 分的程序员对此有何评价。
  • 那么是不是需要释放数组所拥有的retainCount呢?我认为我不必考虑释放自动释放对象“拥有”的计数,因为NSAutoreleasePool 会处理它?

标签: iphone objective-c cocoa-touch


【解决方案1】:

您不必担心对象的保留计数,尤其是因为 NSArray 或其他对象可能会保留,然后才释放您传递给它们的东西。我强烈建议将注意力集中在 Objective-C 和 Cocoa's memory management rules 上,它们可以确保在需要时进行清理。

【讨论】:

  • 最后一个问题,Apples 文档说You create an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” ,你必须释放它。但是我必须releaseretained 的对象吗?
  • 这确实是一个单独的问题,但答案是当您保留某些东西时,您就拥有它,是的,您必须稍后释放它。在您问题的示例中,newCount 设置为一个 ivar,该 ivar 将在下一次调用 setCount 时或在该类的 dealloc 中释放。
【解决方案2】:

这不是要从现有答案中删除,而是要解决您的编辑问题(顺便说一句,这应该是一个单独的问题。):

他们保留了一个 NSNumber 对象并且它从未被释放,这样可以吗?

- (void)setCount:(NSNumber *)newCount {
[newCount retain];
[_count release];
// Make the new assignment.
_count = newCount;
}

好吧,如果他们这样做了,那就不会了。 您将指针与对象混淆了。您是否在 newCount 之前看到了 (NSNumber *)。 '*' 意味着 newCount 是一个指向 NSNumber 对象的指针。请允许我翻译。

[newCount retain];

保留指针“newCount”所指的对象。

[_count release];

向“_count”指针当前引用的对象发送释放消息。

_count = newCount; 

使指针“_count”指向指针“newCount”所引用的对象

这样想,如果你有车,你可能就叫它myCar。当您说myCar 时,您的意思是您的汽车,您拥有的汽车。假设你买了一辆新车一段时间,你会叫它newCar,这样你就可以分辨出区别了。因此,您拥有了您的新车[newCar retain],并在短时间内拥有了两辆车。现在你卖掉了你的旧车,你仍然叫它myCar[myCar release](很伤心)。但是现在当您说 myCar 时,您的意思是您的 newCar myCar = newCar。你不再拥有你的旧车。现在你的 newCar 就是 myCar 并且你拥有、保留那辆。当你死了,dealloc,你的车会被卖掉,[myCar release].

【讨论】:

  • 所以基本上,您不必release newCount 因为我们没有alloc/new/copy 它。 newCount 只复制对_count 的引用(这是内存中的同一个对象),所以不必是release。我说的对吗?
  • 响应编辑,你需要了解对象与指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-26
  • 2022-01-08
  • 2015-01-07
  • 2016-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多