objective-c Objective C 发布、自动发布和数据类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1219575/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Objective C release, autorelease, and data types
提问by Michael
I'm new to memory managed code but I get the idea pretty well.
我是内存管理代码的新手,但我很好地理解了这个想法。
On taking my app through the leaks tool in XCode, I noticed I only had to clean up my custom objects, but not dynamically created arrays for example, so I figured those data types are autoreleased - makes sense since I only had to release the arrays I used as properties that had a (retain) on them.
在让我的应用程序通过 XCode 中的泄漏工具时,我注意到我只需要清理我的自定义对象,而不是动态创建的数组,例如,所以我认为这些数据类型是自动释放的 - 因为我只需要释放数组是有道理的我用作具有(保留)的属性。
Then I noticed something peculiar : I was getting a leak on a certain array initialized like this :
然后我注意到一些奇怪的事情:我在某个初始化的数组上出现了泄漏,如下所示:
NSMutableArray *removals = [NSMutableArray new];
but not a similar one
但不是类似的
NSMutableArray *removals = [NSMutableArray arrayWithCapacity:9];
Now, the reason one was set up with "new" is that it could have 0-99 items in it, whereas the other one I knew was going to always be 9. Since both arrays are passed to the same method later based on user interaction, I was either getting a leak if I did not release at the end of the method, or an exception if I did!
现在,一个设置为“new”的原因是它可能有 0-99 个项目,而我知道的另一个项目将始终是 9。由于两个数组稍后根据用户传递给相同的方法交互,如果我没有在方法结束时释放,我要么得到一个泄漏,要么如果我这样做了一个异常!
I changed the first array to
我将第一个数组更改为
NSMutableArray *removals = [NSMutableArray arrayWithCapacity:99];
and I get no leaks and don't have to release anything. Can anyone explain?
我没有泄漏,也不必释放任何东西。谁能解释一下?
回答by John Calsbeek
As noted in the memory management rules, whenever you have an object that you have created with +alloc, +new, -copy, or -mutableCopy, you own it and are responsible for releasing it at some point. (In fact, +newis just shorthand for [[MyClass alloc] init].) As you noted, creating an array via [NSArray new]without releasing it is a memory leak. However, if you handle this object properly, it is usually possible to release it at some point. For example:
正如内存管理规则中所述,只要您拥有使用+alloc、+new、-copy、 或创建的对象,您就-mutableCopy拥有它并负责在某个时刻释放它。(实际上,+new只是 . 的简写[[MyClass alloc] init]。)正如您所指出的,创建一个数组 via[NSArray new]而不释放它是内存泄漏。但是,如果您正确处理此对象,通常可以在某个时候释放它。例如:
If the method that usesthe array is called from withinthe method that creates the array, then you should be able to release the array after it has been used. If the inner method needs to keep a more permanent reference to the array around, then that method is responsible for sending
-retainand, eventually,-releaseto the object. For example:- (void)myMethod { NSArray *removals = [NSArray new]; // ... [someObject someOtherMethod:removals]; [removals release]; }If you created the array in an
-initmethodfor an object, then the-deallocmethodcan release it when the object is destroyed.If you need to create the array and then returnit from the method, you've discovered the reason that autoreleasing was invented. The caller of your method isn't responsible for releasing the object, since it isn't an
+alloc,+new,-copy, or-mutableCopymethod, but you need to ensure it is released eventually. In this case, you manually call-autoreleaseon the object before you return it. For example:- (NSArray *)myMethod { NSArray *removals = [NSArray new]; // ... return [removals autorelease]; }
如果该方法使用数组是从所谓的内创建数组的方法,那么你应该能够释放数组已经使用之后。如果内部方法需要保持对周围数组的更持久的引用,则该方法负责发送
-retain并最终发送-release到对象。例如:- (void)myMethod { NSArray *removals = [NSArray new]; // ... [someObject someOtherMethod:removals]; [removals release]; }如果您在对象的
-init方法中创建了数组,则该-dealloc方法可以在对象销毁时释放它。如果您需要创建数组,然后从方法中返回它,您就会发现发明自动释放的原因。方法的调用者不负责释放对象,因为它不是
+alloc,+new,-copy, 或-mutableCopy方法,但您需要确保它最终被释放。在这种情况下,您可以-autorelease在返回对象之前手动调用该对象。例如:- (NSArray *)myMethod { NSArray *removals = [NSArray new]; // ... return [removals autorelease]; }
When you create the array via +arrayWithCapacity:, you aren't calling one of the "special" methods, so you do not have to release the result. This is probably implemented with -autorelease, much like the last example above, but not necessarily. (Incidentally, you can also create an empty autoreleased NSMutableArray with [NSMutableArray array]; the method is found in NSArray, so it won't show up in the documentation under NSMutableArray, but it will create a mutable array when sent to the NSMutableArray class.) If you're going to be returning the array from your method, you can use this as shorthand for [[[NSMutableArray alloc] init] autorelease]—but it is just a shortcut. In many situations, though, you can create an object with -initor +newand manually release it at the appropriate time.
当您通过 创建数组时+arrayWithCapacity:,您不会调用“特殊”方法之一,因此您不必释放结果。这可能是用 实现的-autorelease,很像上面的最后一个例子,但不一定。(顺便说一句,你也可以创建一个空的自动释放的 NSMutableArray [NSMutableArray array];该方法在 NSArray 中找到,所以它不会出现在 NSMutableArray 下的文档中,但它会在发送到 NSMutableArray 类时创建一个可变数组。)如果你' 将从您的方法中返回数组,您可以使用它作为简写[[[NSMutableArray alloc] init] autorelease]- 但它只是一个快捷方式。但是,在许多情况下,您可以使用-init或来创建对象+new并在适当的时间手动释放它。
回答by Tuan
This is how things implemented behind the scene:
这就是幕后实现的方式:
+(NSMutableArray*) new
{
return [[NSMutableArray alloc] init];
}
and
和
+(NSMutableArray*) arrayWithCapacity:(NSNumber)capacity
{
return [[NSMutableArray alloc] initWithCapacity:capacity] **autorelease**];
}
In first case the array is allocated only and you're responsible for de-allocating it. In contrary the arrayWithCapacity has autoreleased for you and won't cause leak even you forget to deallocate.
在第一种情况下,仅分配数组,您负责取消分配它。相反,arrayWithCapacity 已为您自动释放,即使您忘记取消分配也不会导致泄漏。
回答by Louis Gerbarg
Cocoa uses certain naming conventions. Anything that starts with alloc, new, or copy returns something with a retainCount of 1 and you are required to release. Anything else that a function returns has a balanced retainCount (it might be held by something else, or it might be retained and out released).
Cocoa 使用某些命名约定。任何以 alloc、new 或 copy 开头的内容都会返回 retainCount 为 1 的内容,并且您需要释放。函数返回的任何其他东西都有一个平衡的 retainCount(它可能被其他东西持有,或者它可能被保留并释放出来)。
So:
所以:
NSMutableArray *removals = [NSMutableArray new];
Has a retainCount of 1, and:
保留计数为 1,并且:
NSMutableArray *removals = [NSMutableArray arrayWithCapacity:99];
or
或者
NSMutableArray *removals = [NSMutableArray array];
Don't since the methods are not prefixed with alloc, new or copy. This is all spelled out in the memory management documentation. In particular:
不要因为这些方法没有以 alloc、new 或 copy 为前缀。这在内存管理文档中都有详细说明。特别是:
You take ownership of an object if you create it using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message. You are responsible for relinquishing ownership of objects you own using release or autorelease. Any other time you receive an object, you must not release it.
如果您使用名称以“alloc”或“new”开头或包含“copy”(例如,alloc、newObject 或 mutableCopy)的方法创建对象,或者向其发送保留消息,则您将获得对象的所有权。您有责任使用 release 或 autorelease 放弃您拥有的对象的所有权。任何其他时候你收到一个对象,你不能释放它。

