简体   繁体   English

NSMutableArray arrayWithCapacity与initWithCapacity

[英]NSMutableArray arrayWithCapacity vs initWithCapacity

I'm an iPhone/Objective-C newbie with an extensive Java background. 我是具有广泛Java背景的iPhone / Objective-C新手。

I'm learning more about memory management in objective-c and I'm reading Apple's documentation on Memory Management: http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html 我正在Objective-C中学习有关内存管理的更多信息,并且正在阅读有关内存管理的Apple文档: http : //developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

In the Object Ownership Policy section, it says that you own any object you create via a method that begins with alloc, new or contains copy. 在“对象所有权策略”部分,它表示您拥有通过以alloc,new或包含副本开头的方法创建的任何对象。 Ownership implies that you need to explicitly release the object when you are done with it. 所有权意味着您需要在完成处理后显式release该对象。

So I'm looking at the NSMutableArray documentation: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/Reference/Reference.html 因此,我正在查看NSMutableArray文档: http : //developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/Reference/Reference.html

There are two methods that pretty much do the same thing...they both create an array with some initial capacity. 几乎有两种方法可以完成相同的工作...它们都可以创建具有一定初始容量的数组。 One is a class method and the other is an instance method. 一个是类方法,另一个是实例方法。

+ (id)arrayWithCapacity:(NSUInteger)numItems;
- (id)initWithCapacity:(NSUInteger)numItems;

Now being the lazy Java developer I am, why would I ever choose the instance method over the class method knowing that at some point in time I have to clean up after myself? 现在我是一名懒惰的Java开发人员,为什么知道在某个时候必须自己清理之后,为什么我还是选择实例方法而不是类方法呢?

I guess I may be missing a fundamental point here...is it simply a matter of determining when the object gets released? 我想我这里可能遗漏了一个基本要点...仅仅是确定对象何时释放的问题吗? autorelease in the class method vs. release in the instance method? 类方法中的autorelease release与实例方法中的release I suppose that on a platform with very limited resources (iPhone) I should refrain from using the class method and release the object as soon as I'm done with it? 我想在资源非常有限(iPhone)的平台上,我应该避免使用类方法,并在完成处理后立即释放该对象?

Thanks! 谢谢!

You will usually choose based on whether or not you are going to own the object for more than the life of the current method (eg, assign it to some static or directly to an ivar). 通常,您将根据是否拥有该对象的时间超过当前方法的寿命来进行选择(例如,将其分配给某个静态对象或直接分配给ivar)。 In that case, you can use the alloc/init method since you know you want to own it already. 在这种情况下,可以使用alloc / init方法,因为您知道自己已经拥有它。 If you plan to only use it for the scope of the current method, or you are assigning it to something managed like a property, then you would probably use the convenience method. 如果计划仅将其用于当前方法的范围,或者将其分配给像属性这样管理的对象,则可能会使用便捷方法。

When you know that you are going to own an object that you are creating, the alloc/init call is always more efficient than the convenience/retain way since the latter is required to basically alloc/init/autorelease the object and then you retain it when it is returned. 当您知道要拥有要创建的对象时,alloc / init调用总是比便捷/保留方式更高效,因为便利/保留方式基本上需要对alloc / init / autorelease对象进行分配,然后再保留它当它返回时。

You might also use the direct alloc/init methods when you are allocating in a loop and don't need/want to deal with an autorelease pool. 当您在循环中分配并且不需要/不想处理自动释放池时,也可以使用直接alloc / init方法。

arrayWithCapacity: already has the autorelease applied to it. arrayWithCapacity:已经对其应用了自动发布。

initWithCapacity: is explicitly retained and you will need to release it yourself. initWithCapacity:已明确保留,您需要自己释放它。 Since you call it usually as [[A alloc] init...], this will trigger a lightbulb "I need to manage the memory for this," other similar magic words besides "alloc" being "new" and "copy" as you read in the memory management guide. 由于您通常将其称为[[A alloc] init ...],因此将触发一个灯泡“我需要为此管理内存”,除了“ alloc”是“ new”和“ copy”以外,其他类似的魔术字还包括:您可以在内存管理指南中阅读。 But from your question, looks like you understand the principles of it well. 但是从您的问题来看,您似乎很了解它的原理。

You are correct that you should keep your memory footprint managed and low, but this does not mean that you need to always do explicit init/release. 您应该对内存的占用空间进行管理并保持较低状态是正确的,但这并不意味着您需要始终进行显式的初始化/释放。 As Nick says, one use case to use autorelease factory methods is when you are passing them around as parameters. 正如Nick所说,使用自动释放工厂方法的一个用例是当您将它们作为参数传递时。

Another example is that when you add something to a collection like NSDictionary or NSArray, that "something" can be created with the autorelease factory method, since the collection "takes over" retaining it. 另一个例子是,当您向NSDictionary或NSArray之类的集合中添加内容时,可以使用autorelease factory方法创建“内容”,因为集合“接管”了它。 (Things are retained when added to collection, and released when removed.) (添加到集合中时将保留所有内容,删除时将其释放。)

You may argue that 您可能会争辩

Blah *blah = [Blah blahWithSomething];
[myMutableArray addObject:blah];

is just cleaner to type than 打字比

Blah *blah = [[Blah alloc] initWithSomething];
[myMutableArray addObject:blah];
[blah release];

In the first case, you do not need to worry about a release call at all. 在第一种情况下,您完全不必担心发布调用。 The downside is that when you do this many times in the same runloop, memory footprint of first case is greater IF it is a temporary/throwaway array object that goes away at the end of the runloop. 不利的一面是,当您在同一运行循环中多次执行此操作时,如果第一种情况的内存占用量更大,则它是一个临时/丢弃的数组对象,在运行循环结束时会消失。 But if it's a small object not done in a loop and retained for longer time as is a common case, their footprints are the same. 但是,如果这是一个很小的对象,而不是循环执行并且要保留更长的时间(通常情况下),那么它们的占用空间是相同的。

In this case I try to stick to the following rules to avoid memory related ( == "very nasty") bugs: 在这种情况下,我尝试遵循以下规则以避免与内存相关的错误(==“非常讨厌”):

  • if you are passing that array as a parameter, then you can use the factory method no problem, since it's the responsibility of the accepting function to retain/release it 如果您要将该数组作为参数传递,则可以使用工厂方法没有问题,因为接受函数负责保留/释放它
  • if you want to keep working with the object, use the initialization method and release the object at the end 如果要继续使用该对象,请使用初始化方法并在最后释放该对象

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM