Use autorelease before adding objects to a collect

2019-01-18 07:17发布

I have been looking through the questions asked on StackOverflow, but there are so many about memory management in Objective-C that I couldn't find the answer I was looking for.

The question is if it is ok (and recommnded) to call autorelease before adding a newly created object to a collection (like NSMutableArray)? Or should I release it explicitly after adding it. (I know NSMutableArray willl retain the object)

This illustrates my question:

Scenario A (autorelease):

- (void) add {
   // array is an instance of NSMutableArray

   MyClass *obj = [[[MyClass alloc] init] autorelease];

   [array addObject:obj];
}

Scenario B (explicit release):

- (void) add {
   // array is an instance of NSMutableArray

   MyClass *obj = [[MyClass alloc] init];

   [array addObject:obj];

   [obj release];
}

I assume both are correct, but I am not sure, and I sure don't know what the preffered way is.

Can the Objective-C gurus shed some light on this?

7条回答
虎瘦雄心在
2楼-- · 2019-01-18 07:39

Both are correct and will work as you're expecting them to.

I personally prefer to use the latter method, but only because I like to be explicit about when objects get released. By autoreleasing the object, all we're doing is saying "this object will get released at some arbitrary point in the future." That means you can put the autoreleased object into the array, destroy the array, and the object might (probably) still exist.

With the latter method, the object would get destroyed immediately with the array (providing that nothing else has come along and retained it in the meantime). If I'm in a memory-constrained environment (say, the iPhone) where I need to be careful about how much memory I'm using, I'll use the latter method just so I don't have so many objects lingering in an NSAutoreleasePool somewhere. If memory usage isn't a big concern for you (and it usually isn't for me, either), then either method is totally acceptable.

查看更多
做自己的国王
3楼-- · 2019-01-18 07:39

I prefer A (autoreleasing) for brevity and "safety", as johne calls it. It simplifies my code, and I've never run into problems with it.

That is, until today: I had a problem with autoreleasing a block before adding it to an array. See my stackoverflow question: [myArray addObject:[[objcBlock copy] autorelease]] crashes on dealloc'ing the array (Update: Turns out the problem was elsewhere in my code, but still, there was a subtle difference in behavior with autorelease…)

查看更多
叼着烟拽天下
4楼-- · 2019-01-18 07:40

They're both OK. Some people will tell you to avoid autorelease because of "overhead" or some such thing, but the truth is, there is practically no overhead. Go ahead and benchmark it and try to find the "overhead." The only reason you'd avoid it is in a memory-starved situation like on the iPhone. On OS X, you have practically unlimited memory, so it isn't going to make much of a difference. Just use whichever is most convenient for you.

查看更多
对你真心纯属浪费
5楼-- · 2019-01-18 07:47

They are both correct but B may be preferred because it has no overhead at all. Autorelease causes the autorelease pool to take charge of the object. This has a very slight overhead which, of course, gets multiplied by the number of objects involved.

So with one object A and B are more or less the same but definitely don't use A in scenarios with lots of objects to add to the array.

In different situations autoreleasing may delay and accumulate the freeing of many objects at the end of the thread. This may be sub-optimal. Take care that anyway autoreleasing happens a lot without explicit intervention. For example many getters are implemented this way:

return [[myObject retain] autorelease];

so whenever you call the getter you add an object to the autorelease pool.

查看更多
叛逆
6楼-- · 2019-01-18 07:48

You have alloc'ed the object, then it's your job to release it at some point. Both code snippets work merely the same, correct way, with the autorelease way being the potentionally slower counterpart.

Personally speaking, I prefer the autorelease way, since it's just easier to type and almost never is a bottleneck.

查看更多
smile是对你的礼貌
7楼-- · 2019-01-18 07:51

You can send the autorelease message at any point, because it isn't acted on until the application's message loop repeats (i.e. until all your methods have finished executing in response to user input).

http://macdevcenter.com/pub/a/mac/2001/07/27/cocoa.html?page=last&x-showcontent=text

查看更多
登录 后发表回答