【问题标题】:Memory allocation for an array of Objects - Is my understanding valid?对象数组的内存分配 - 我的理解是否有效?
【发布时间】:2012-05-03 16:45:37
【问题描述】:

我有一个关于数组中对象的内存分配的问题。我希望创建一个对象数组,但在编译时,我无法知道需要多少对象,因此不想保留比需要更多的内存。

我想做的是根据需要分配内存。我想这样做的方式是当用户单击“添加”按钮时,数组会增加一个额外的对象,并分配新对象所需的内存。

在我对Objective C的新手理解中(大约20年前我是一名专业程序员,最近才开始重新编写代码)我想出了以下代码段:

首先,我声明了我的对象:

    NSObject *myObject[1000]; // a maximum number of objects.

然后,当用户单击“添加”按钮时,它会运行一个带有分配代码的方法:(注意:变量 i 从值 1 开始,每次单击“添加”按钮时都会增加)

    ++i
    myObject[i] = [[NSObject alloc] init];

因此,我希望只为实际需要的对象分配内存,而不是立即为所有 1000 个数组对象分配内存。

我的解释正确吗?换句话说,我的解释是否正确,声明中声明的数组元素的数量是数组元素的最大可能数量,而不是当时分配了多少内存?如果这是正确的,那么理论上,声明:

    NSObject *myObject[10000];

不会比声明更多的内存:

    NSObject *myObject[5];

有人可以确认我正确理解了这个过程,如果我有这个混淆,请赐教。 :)

谢谢!

【问题讨论】:

  • 为什么不使用 NSMutableArray 或 CFMutableArray?它有效地添加对象。这里是 CFArray 的源代码,如果你想看看:opensource.apple.com/source/CF/CF-635/CFArray.c
  • 感谢您的提示。我确信这可能是我应该这样做的方式。直到现在我都没有听说过其中任何一个。奇怪的是,虽然我知道我可能在重新发明轮子,但理论上我对内存分配的理解是否准确?
  • 永远不要使用 Objective-C 对象的 C 数组,这是个坏主意。使用语言提供的数组对象。我强烈推荐你阅读一本 Objective-C 的书。最好的(恕我直言)是 Programming In Objective-C,作者是 Stephen Kochan。
  • 此外,您还可以通过 CFArray/NSArray 获得许多有用的方法/功能。使用 NSArray,你可以做一些花哨的事情,比如 -makeObjectsPerformSelector: 让它们都调用一个方法,或者使用块或使用 for (<class name> *<object name> in <array name>){// do stuff} 的 Objective-C 快速枚举
  • Rob - 我有那本特别的 Objective-C 书,并且一直在研究它。我只是碰巧在前进并进行实验……有时这会有所帮助,有时会像这种情况一样将我引向完全错误的方向:)

标签: objective-c cocoa memory object alloc


【解决方案1】:

为什么不使用 NSMutableArray?您可以 initWithCapacity 或简单地使用 [NSMutableArray 数组] 进行分配。当您添加和删除对象时,它会增长和缩小。例如:

NSMutableArray *array = [NSMutableArray array];
NSObject *object = [[NSObject alloc] init];

[array addObject:object]; // array has one object
[array removeObjectAtIndex:0]; // array is back to 0 objects

// remember to relinquish ownership of your objects if you alloc them
// the NSMutable array was autoreleased but the NSObject was not
[object release]; 

【讨论】:

  • 查看 NSMutableArray 和 NSArray 文档以了解它们拥有的所有其他很酷的功能。 developer.apple.com/library/ios/#documentation/Cocoa/Reference/…
  • NSArray 在收到对 dealloc 的调用时释放其所有对象。这就是为什么如果你有一个类型为NSArray 的综合属性,你只需要释放-dealloc 中的NSArray 而不是它的内容。
  • @JackLawrence,这是正确的,但是在对象上调用 alloc 会将其保留计数增加 1。将该对象添加到 NSArray 也会将其保留计数增加到 2。如果我没有调用 [object release]当我这样做时,从数组中删除对象会使对象保留计数为 1,从而防止内存被系统回收。
【解决方案2】:

您的理解大部分是正确的。当你这样做时:

NSObject *myObject[1000];

您立即为 1000 个指向 NSObject 实例的指针分配存储空间。在您执行 [[NSObject alloc] init] 之前,不会分配 NSObject 实例本身。

但是,执行NSObject *myObject[10000] 将比执行NSObject *myObject[5] 消耗更多空间,因为10,000 个指针肯定需要比5 个指针更多的内存来表示。

请记住,这两个东西都消耗空间,指向NSObject 的指针和NSObject 实例本身,尽管实际上NSObject 实例消耗的空间将明显大于指针消耗的4 个字节那是指它。

无论如何,也许更重要的是,在 Cocoa 中有一种更好的方法来管理动态对象分配。使用内置的NSMutableArray 类。喜欢:

NSMutableArray* objects = [[NSMutableArray alloc] init];
[objects addObject: [[[NSObject alloc] init] autorelease]];

【讨论】:

  • 很好的解释。谢谢。我完全忘记了指针本身已分配内存的事实。本质上,对象基本上是一种数据库记录。一个 NS 对象,包含一堆变量和一些方法。
  • 现在,我可以使用访问器方法访问对象中的变量,例如:x = [myObject var];如果我将 myObject 添加到数组对象中,是否有一种简单的方法可以使用 myObject 的访问器方法?我确信它是这样的:x = [[objects ] var];
  • 是的,很接近。这是x = [[objects objectAtIndex:<index>] var]。您可能会发现reference docs 很有用。
猜你喜欢
  • 2013-12-04
  • 2020-06-02
  • 1970-01-01
  • 2011-06-03
  • 2012-05-04
  • 2015-10-15
  • 2013-01-20
  • 1970-01-01
相关资源
最近更新 更多