what if we retain or autorelease pool? why? - objective-c

Language : Objective C
Questions:
why we should always use 'drain' over 'release' for an autorelease pool ?
what will happen if [pool retain]; ? why ?
what will happen if [pool autorelease]; ? why ?

The documentation doesn't give a direct answer to this. However, there is a very clear answer; because it doesn't make sense.
P.S: drain and release are the exact same thing on an autorelease pool.

Under garbage collection, release acts as a no-op, whereas drain triggers garbage collection, and then release (which is unusual), so drain should be the preferred way of emptying a pool. retain and autorelease are intentionally disabled, as per the documentation.

WWDC 2011 Session 323, Introducing Automatic Reference Counting, explains that autorelease pools are not real objects, so they cannot be retained. Retaining an autorelease pool will cause an exception. Watch the video at 24:27 or read slide 23 of the Keynote. You must be a registered developer to access.
Under ARC, autorelease syntax is a scoped block of code preceded by #autorelease. According to Apple, this syntax more accurately describes what autorelease does under the hood.

Related

Objective-C Memory Management: Am I understanding this?

I've finally decided to stop beating around the bush and teach myself some Objective-C. It's all making sense, except when I get to the memory management and this idea of the "autorelease pool".
From my understanding, if I specifically create an object using init,new, alloc or tell it to retain, then it is my job to deallocate the memory. However, an autorelease pool will automatically free up any objects associated with the innermost autorelease pool?
For example, say I do this:
TestOBJ* foo = [[[TestOBJ alloc] innit] autorelease];
Then it will be released at the end of the first #autoreleasepool block, or whenever the first [autoreleasepool drain] is called?
Also; just because an object is created within an autoreleasepool block doesn't mean it is automatically labeled as autorelease, correct?
Correct for both points.
Objects only get added to autorelease pools if you call -autorelease on them. By convention all methods not starting with alloc, new, copy or mutableCopy return objects that they have themselves added to the autorelease pool, so you don't have to do it yourself.
See http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html for details.
You pretty much answered all your questions yourself correctly.

Thread with lot of autoreleased objectIs is it mandatory to use autorelease pool on this scenario if yes/no why?

Consider we are implementing our own thread with lot of autoreleased object. Is it mandatory to use autorelease pool on this scenario if yes/no why?
It's mandatory to have an autorelease pool on any thread that you create, because Cocoa internals expect there to be one in place and you will leak memory if it isn't there.
Cocoa always expects there to be an autorelease pool available. If a pool is not available, autoreleased objects do not get released and your application leaks memory. If you send an autorelease message when a pool is not available, Cocoa logs a suitable error message.
Applications that link in Objective-C frameworks typically must create at least one autorelease pool in each of their threads.
It is mandatory even with a single autoreleased object, because otherwise it will leak.

Objective C - Memory Management and autorelease ???

Does autorelease guaranty that at the end of blocks the object will get released?
Or is it better to manually release objects?
It guarantees it will be released sometime after the block executes, not necessarily immediately after. It's up to the runtime to determine exactly when.
It's not big deal unless you're doing something with a lot of autoreleased variables, like creating them in a big loop, or if you're creating large autoreleased objects, like UIImages. In these cases, you should manually release when you're through, otherwise autorelease is perfectly acceptable.
If an object is autoreleased, you MUST not manually release it (unless it is retained of course). The NSAutoRelease pool which is part of the UIKit event handler will release it for you. If you were to manually release the object, the pool may cause a crash or other undefined behavior as the object will be doubly-released.
If there are cases where you generate a lot of objects or use a lot of memory in objects, you can pre-emptively autorelease them (perhaps in your loop) by creating your own NSAutoReleasePool - pools can be nested.
It's better to release objects rather than autorelease, unless of course you have an explicit reason to use autorelease, for example use autorelease when returning an object the method retained and you can't avoid it.
Basically autorelease should be used as an excuse to completely avoid memory management. You want to release objects as soon as you possible can. Autorelease just says the object will be released some time in the future.

Can I early-release an autorelease object?

i.e. would cause the object to be released immediately and not have to be released by the pool if I did this?
[[NSArray arrayWithCapacity:100] release];
Can't find a clear explanation in the docs about this.
It would likely crash when the object would normally be autoreleased. autorelease means "delayed release", so it will be released: just later. Since the object won't exist later as you are manually releasing it, you will likely crash due to the runtime sending the -release message to your now-deallocated object.
Edit: Note that if you -retain objects that come autoreleased, you do have to -release them: you are taking ownership.
I realise that this is stupid now, and that I shouldn't be releasing something I don't own.
If you don't want the object to go into the auto-release pool, you can do a manual alloc and initWithCapabity. If you do that, you'll have to manually release it at some point.

What is the difference between releasing and autoreleasing?

I still have some unclear understand about release and autorelease. What are the difference between both of them? I have this code. For facebook connection. I crash it sometimes when I go to Facebook login, I doubting maybe it is because I don't release the object nicely.? Thanks for any helps
if (_session.isConnected) {
[_session logout];
} else {
FBLoginDialog* dialog = [[[FBLoginDialog alloc] initWithSession:_session] autorelease];
[dialog show];
}
The Memory Management Programming Guide for Cocoa will soon be your best friend. In brief, object instances in Cocoa are memory managed using reference counting (unless, of course you're using garbage collection on OS X). An object indicates that it wants to 'retain' an ownership interest in an other instance--keep it from being deallocated--by sending it a -retain message. An object indicates that it wants to release that interest by sending the other instance a -release message. If the number of objects that have 'retained' and ownership interest in an object drops to 0 (i.e. when the last of the owning instances sends a -release message), the instance with a 0 retain count is deallocated.
It's sometimes convenient to say "I want this instance to be released some time in the future". That's the purpose of -autorelease. Sending an -autorelease message adds the receiver to the current NSAutoreleasePool. When that pool is drained, it sends a -release message to all the instances in the pool. An NSAutoreleasePool is automatically created at the start of each iteration of each thread's run loop and drained at the end of that iteration. Thus, you can do something like this in a method:
- (id)myMethod {
return [[[MyObject alloc] init] autorelease];
}
The caller of this method will get back an instance that they can -retain if they wish to keep it. If they don't retain it, it will stick around at least until the enclosing autorelease pool is drained:
- (void)someOtherMethod {
...
id instance = [obj myMethod];
... // do more with instance, knowing that it won't be dealloc'd until after someOtherMethod returns
}
Releasing means you release that right away.
Autoreleasing means you want the variable to be released on the next autorelease pool.
You use autorelease when you want to keep retaining the variable but don't want to create a memory leak. You use release when you don't need the variable anymore.
Sample:
- (NSNumber *)return5 {
NSNumber * result = [[NSNumber alloc]initWitnInt: 5];
[result autorelease];
return result;
}
Why do we use autorelease there?
If we use [result release] instead, variable result will be destroyed AT that time. Which means that the returned value will be garbage.
If we do not release at all, variable result will be hold FOREVER incurring memory leak.
We can tell every caller to the function to release result but that would be a headache and prone to error.
So we use autorelease. We mark the variable to be released on the next autorelease pool. Basically we mark the variable to be released near the alloc. Hence the mantra alloc is paired with release in the same function holds all the time.
Actually, you'll do fine changing all release into autorelease. Your memory use won't be efficient, however, the effect is minimal. All variables, in all programming language is effectively autoreleased.
Anyway, use ARC.
background discussion:
objective-c is reference counted, so objects are deleted when the reference count reaches 0. release reduces the reference-count immediately, autorelease reduces it when the autorelease-pool is popped
when to use:
use autorelease when allocating the object if
you do not need it after the current function
it will be retiained by some other objet/function and will be released by a later by the retaining code
when the logic of the current function is tricky, so you would have to send release in a dozen different places before doing a return
use "manual" release
to revert a previous retain (in case you are implementing a library)
if you need precise control of freeing objects (e.g. they use lots of memory or the autorelease pool will not be popped for some time)
but really my freand:
read the Memory Management Programming Guide for Cocoa as suggested by Barry and run your code with instruments (zombies and leaks) often to catch any and almost all memory management errors.
Erik
According to the Memory Management Programming Guide for Cocoa:
The autorelease method, defined by
NSObject, marks the receiver for later
release. By autoreleasing an
object—that is, by sending it an
autorelease message—you declare that
you don't want to own the object
beyond the scope in which you sent
autorelease.
Also:
The autorelease method thus allows
every object to use other objects
without worrying about disposing of
them.