Objective-C Memory Management: When do I [release]? - objective-c

I am still new to this Memory Management stuff (Garbage Collector took care of everything in Java), but as far as I understand if you allocate memory for an object then you have to release that memory back to the computer as soon as you are finished with your object.
myObject = [Object alloc];
and
[myObject release];
Right now I just have 3 parts in my Objective-C .m file: #Interface, #Implementation and main. I released my object at the end of the program next to these guys:
[pool drain];
return 0;
But what if this program were to be a lot more complicated, would it be okay to release myObject at the end of the program?
I guess a better question would be when do I release an object's allocated memory? How do I know where to place [myObject release];?

This is probably a little over-simplified, but in general, you are going to want to release it where you declared it.
If you declare an object INSIDE a particular method call, then by definition, you will be done with that object (or at least that handle to that object) at the end of that method call... release it then.
If you declare an object as an instance variable, then by definition you will be done with it when that instance is destroyed... release it in the dealloc method of that class.
Keep in mind that "release" does not equal "destroy." When passing objects around in your application, it may make sense to have more than one handle to that object stored in different places... in that case "release" means "I'm done with this object, but someone else may still be using it." Deallocation only occurs when the number of "handles" (retain count) reaches zero.
Apple has some fantastic documentation on memory management, I would check it out at developer.apple.com.

You essentially have three kinds of objects, each with a different pattern.
Transients Objects
In general, you should autorelease transient objects. These are objects that are allocated locally and do not need to exist beyond the method in which they are called. Or they are passed around from method to method.
Chain of Ownership
When one object exists as an instance field inside another, you should release the "owned" (or "child") object when the "owner" (or "parent") object goes out of existence. This is done in the dealloc method of the parent object:
- (void) dealloc {
[child release]; // child was declared as an instance variable
[super dealloc];
}
Lifetime of the Program
When an object is intended to exist for the lifetime of the program, it usually isn't necessary to call release at all, unless some kind of resource cleanup needs to occur. You can put this in applicationWillTerminate:, which you can look up in Apple's documentation.
(You should probably avoid having such objects, but that is a discussion for another question.)

You have to think in terms of ownership. When you take ownership of an object by calling alloc, new or retain, you're also responsible for releasing it, either by calling autorelease when you return an owned object to the caller, or by calling release.
A general rule is:
Local variable: release it within the same method. When you want to return it to the caller, use autorelease
Class member: release it in the dealloc method

Related

release for objects on Class method?

Without using ARC, for objects initialized using instance method we do release it via release call.
example:
Sample *obj = [[Sample alloc]init] ;
// some code here
[obj release] ;
Now for objects allocated using class methods should release be called?
example:
TestSample *testobj = [TestSample initCustom] ;
// some code here
should there be [testobj release]?
Let's consider this standard function provided by apple.
endpointWithHostname is a class method.
NWHostEndpoint *pNetHost = [NWHostEndpoint endpointWithHostname:#"0.0.0.0" port:#"21"];
so, should there be a [pNetHost release] for above call?
You said:
for objects initialized using instance method we do release it via release call
The fact that you called an instance method isn’t relevant. You own any object returned by any method whose name starts with alloc, new, copy, or mutableCopy. In your example, you called alloc, and therefore ownership has been transferred to you. That’s why you are now responsible for calling release.
However, if you called some instance method that didn’t start with one of those four prefixes, though, ownership would not be transferred to you, and you would not call release.
This is all summarized in the Advance Memory Management Programming Guide, which says:
Basic Memory Management Rules
The memory management model is based on object ownership. Any object may have one or more owners. As long as an object has at least one owner, it continues to exist. If an object has no owners, the runtime system destroys it automatically. To make sure it is clear when you own an object and when you do not, Cocoa sets the following policy:
You own any object you create
You create an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy).
You can take ownership of an object using retain
A received object is normally guaranteed to remain valid within the method it was received in, and that method may also safely return the object to its invoker. You use retain in two situations: (1) In the implementation of an accessor method or an init method, to take ownership of an object you want to store as a property value; and (2) To prevent an object from being invalidated as a side-effect of some other operation (as explained in Avoid Causing Deallocation of Objects You’re Using).
When you no longer need it, you must relinquish ownership of an object you own
You relinquish ownership of an object by sending it a release message or an autorelease message. In Cocoa terminology, relinquishing ownership of an object is therefore typically referred to as “releasing” an object.
You must not relinquish ownership of an object you do not own
This is just corollary of the previous policy rules, stated explicitly.
You go on to ask:
let's consider this standard function provided by apple. endpointWithHostname is a class method.
NWHostEndpoint *pNetHost = [NWHostEndpoint endpointWithHostname:#"0.0.0.0" port:#"21"];
so should there be a [pNetHost release] ; for above call
The fact that it is a class method isn’t relevant. The key is that the method name doesn’t start with alloc, new, copy, or mutableCopy. That means that ownership has not been transferred to you and therefore you don’t need to call release. In this case, it is returning an autorelease object, so it will be released for you when the autoreleasepool is drained.
Obviously, if you want to claim ownership of the pNetHost object, you would do so by calling retain (and of course, at that point you’d then be responsible for eventually calling release to offset that retain).
Now, let’s consider your example:
TestSample *testobj = [TestSample initCustom];
// some code here
should there be [testobj release]?
No. But let’s answer this question by looking at the implementation of the method you called initCustom. It might be implemented like so:
+ (instancetype)testSample {
TestSample *obj = [[self alloc] init];
// perhaps more customization of `obj` here
return [obj autorelease];
}
But, there are two key observations in the above:
I didn’t start the method name with init. That prefix should only be used with initialization methods, which this method isn’t.
The convention is to start the method name with the name of the object type, using camelCase (i.e. starting with a lowercase letter). Hence, this TestSample class method name might be called testSample, like above, not initCustom.
Because the method name doesn’t start with alloc, new, copy, or mutableCopy, it should return an autorelease object. And because it is an autorelease object, the caller would therefore would not call release (unless, of course, it claimed ownership by calling retain).
By the way, the static analyzer (shift+command+B; or “Product” » “Analyze”) is exceptionally good at analyzing manual reference counting code.
For example, let’s imagine that I forgot to add the autorelease in the above testSample example. If I let Xcode analyze the code, the compiler would tell me about the problem:
If I add the autorelease back in and re-analyze, this warning will go away.
When writing manual reference counting code, the static analyzer is an invaluable tool. Always make sure you have a clean bill of health from the analyzer.

Dealloc method isn't called when i release perticular object

I have created an object using alloc/init method, and after I release it -dealloc should be called immediately as per documentation. I set a breakpoint on -dealloc method but it isn't hit, and my -dealloc method is not called.
Please tell me what is the reason behind that, and what is use of dealloc method in objective c ?
The -dealloc method is not always called when you expect it to be called. The runtime might also have issued a -retain on your object for internal reasons.
It's also possible that you have (directly or indirectly) caused an extra -retain to be issued. If the retains/allocs and releases are not balanced, you'll never see -dealloc called. It helps to turn on the Static Analyzer, to make sure your calls balance.
Just follow the memory management rules, don't second guess the runtime, and let the memory management system do its job.
The answers to When does dealloc method call? may help you understand what you're seeing.
because it still has reference. that means its reference count not reached to zero. i don't know your code, where it is referencing. but it is not calling that means somehow still it has reference. it may be because of strong relationship or parent-child relationship
all Objective-C objects are allocated on the heap, so they must
therefore be deallocated somewhere if you are not to run out of
resources.
This gave way to the reference counting method, which is still used
today: each object keeps count of any references held to it. If you
receive an object and you want to keep it, you retain that object,
incrementing its reference count. When you are done with it, you
release it, which decrements its reference count. Once that count
reaches zero, it is inferred that no one is referencing the object and
it is automatically deallocated using the -dealloc method.
Additionally, an object could be told to “release at some point in the
(hopefully) near future” using autorelease pools. The idea is that
somewhere on the stack (typically at the start of a thread or while
responding to input events) an autorelease pool is created and pushed
onto a stack. Any object can then be sent an -autorelease message, and
it is assigned to that pool.
When the pool object is deallocated, it simply sends a -release
message to all its assigned objects. That way, any objects that are no
longer used (i.e. they haven’t been explicitly retained) are then
deallocated.
The dealloc is called (at more cases) whenever your object is released. You can't directly call this method.
#interface myViewController:UIViewController
{
NSString *myStr;
}
#end
Here the dealloc method in the #implementation of myViewController will be called (at most cases) when the myViewController object is released, not when myStr is released.
Although you don't have to use if you ARC.

Objective C: Memory Leak in non-void instance method

I am getting another memory leak in a non-void instance method that returns a object of class NSMutableArray.
Can someone advise me on how I can fix this leak? I tried to release 'userFollowings' at the end of the method but it's still reporting a leak.
When your are to return an object from a method in which you have either initialized it or retained it, it is common practice to return it autoreleased. That way, the user receiving the object doesn't have to worry about releasing it. So, your final line of code should look like this:
return [userFollowing autorelease];
It probably wouldn't hurt to read a little from the Memory Management Programming Guide to catch up on memory management rules such as this, and there are plenty of other helpful resources out on the web and on this site.
There are a set of conventions used by Cocoa programs that make memory management much less error prone. When a method returns an object, the code that calls it needs to know if it owns it or not.
What it boils down to is that if you are writing a method that returns an object and that method doesn't convey ownership upon the caller by being named something like new, alloc, copy, etc., you need to autorelease it before you return it.
That's what the message you are getting is talking about - "Object returned to caller as an owning reference" means that you're conveying ownership on the calling code. The problem is that your method name indicates otherwise.
If I were to call your method and needed to hang onto the object, I'd call retain on it so that I owned it. I need to do this because your method name implied I wasn't the owner. So long as you are returning an autoreleased object, that's correct. But if you don't autorelease the object, it will end up with a retain count of 2 - once when you allocated it and once when I retained it. When I finally get round to releasing it, it will still have a retain count of 1, and will never be deallocated from memory, resulting in a memory leak.
The problem is that userFollowings never gets released. Try ending with
return [userFollowings autorelease];
Try this:
NSMutableArray* userfollwings = [[[NSMutableArray alloc] init] autorelease]

using alloc and init

We know about the complete pattern of alloc/init that alloc and init must be combined.
NSObject *myObj = [[NSObject alloc] init];
1- init method receives the object from another source(not from a alloc,new,copy or alike or retained) so according to the fundamental memory management rule its not the owner and it must not release it. However, "Allocating and Initializing Objects / The Returned Object" article says that init could free the receiver.
How could this be possible when its against the fundamental rule?
2- Also, from the same article, init could return another object or nil. So, in this case, when we use the complete pattern of alloc/init, we could not release the object returned by alloc but we could only release the object returned from init and, init releases the object it received from alloc instead of us.
But init is not a alloc,new,copy or alike method so we must not release the object returned from it as it does not give us the ownership of object.
How could we release the object returned from init although this is against the fundamental rule?
3- Or, to adhere to the last paragraph of the same article, must we accept init method as a special case and use alloc/init pattern as an exception to the fundamental rule?
Memory Management Fundamental Rule:
You only release or autorelease objects you own.
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 use release or autorelease to relinquish ownership of an object. autorelease just means “send a release message in the future” (to understand when this will be, see “Autorelease Pools”).
http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html
Allocating and Initializing Objects / The Returned Object:
However, in some cases, this responsibility can mean returning a different object than the receiver. For example, if a class keeps a list of named objects, it might provide an initWithName: method to initialize new instances. If there can be no more than one object per name, initWithName: might refuse to assign the same name to two objects. When asked to assign a new instance a name that’s already being used by another object, it might free the newly allocated instance and return the other object—thus ensuring the uniqueness of the name while at the same time providing what was asked for, an instance with the requested name.
In a few cases, it might be impossible for an init... method to do what it’s asked to do. For example, an initFromFile: method might get the data it needs from a file passed as an argument. If the file name it’s passed doesn’t correspond to an actual file, it won’t be able to complete the initialization. In such a case, the init... method could free the receiver and return nil, indicating that the requested object can’t be created.
Because an init... method might return an object other than the newly allocated receiver, or even return nil, it’s important that programs use the value returned by the initialization method, not just that returned by alloc or allocWithZone:. The following code is very dangerous, since it ignores the return of init.
id anObject = [SomeClass alloc];
[anObject init];
[anObject someOtherMessage];
Instead, to safely initialize an object, you should combine allocation and initialization messages in one line of code.
id anObject = [[SomeClass alloc] init];
[anObject someOtherMessage];
http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocAllocInit.html
The init method doesn't receive the object; the object receives the init message. The object does not possess itself; rather, it always knows about itself (through the implicit self argument in every message).
You're right that the object does not own itself, though. If alloc and init were fused in a single new method, that method would be its own (super) caller, so it would own the object (until it returns) and so be unquestionably right in releasing it. Since they are separate, and init is not the caller of alloc, you're right that it does not own the object, so you are right to question this practice.
This is one of the few cases where it's OK for one object to release an object (in this case, itself) on behalf of another. The alternative is not to release it, which, if you're going to either return nil or throw an exception, will be a leak.
In general, anytime you have an object retain or release itself, you should feel dirty. In this specific case, it's OK, because you are preventing a bug (a leak) rather than probably creating one.
2- Also, from the same article, init could return another object or nil. So, in this case, when we use the complete pattern of alloc/init, we could not release the object returned by alloc but we could only release the object returned from init and, init releases the object it received from alloc instead of us.
But init is not a alloc,new,copy or alike method so we must not release the object returned from it as it does not give us the ownership of object.
As init releases the old object on behalf of its caller, if it creates a new object, it does that on behalf of its caller. The caller does own the substitute object that init creates or retrieves for it.
As a corollary to this, if init retrieves a previously existing object, it must retain that, so that the caller will own it.
Again examining the hypothetical* new method, it would also need to both release the old object and create (owningly) or retain the substitute.
In all of these cases, it's init acting on behalf of its caller. It's normally dodgy for one method to do another's memory management, but for these cases, init doing it on behalf of its caller is necessary.
*The new method does exist, but simply sends alloc and init, so there's no need to implement it separately.
If initialization fails for some reason and must return null, then you must release the object in order to avoid leaking memory.
Similarly, init may decide to swap in a different object and return it - in that case you must also release the object in order to avoid leaking memory.
In both cases it's necessary because the original object isn't being returned by init, and will be orphaned after the method returns. Alloc has automatically retained the object, so if you don't release it its retain count will be stuck at 1 forever.
[Would another perspective help?]
The init method (and its siblings initWith... and similar) is a bit of an odd case but is not a special case of memory allocation rules. Init is odd because it has a name that sounds like it is going to change the internals of the instance but in fact it may do more than that (it may substitute some other object and initialize that object, for example). The tip-off is in the declaration of init:
- (id) init // the way it is
vs
- (void) init // in some other universe
The init method returns an object, so it might have been better named something like 'return an object that is (class-wise) an equivalent object and that has been initialized'. Most methods do not perform this kind of switcheroo, which makes init a bit different/odd.
There is nothing 'magic' about the alloc / init nesting -- it's just the simplest way to handle the fact that the object that you get back from alloc may not be the same object you get back from init. This works perfectly fine:
NSSomeClass* s = [NSSomeClass alloc];
s = [s init]; // that 's =' part is really important ;-)
and is exactly equivalent to the 'standard' idiom:
NSSomeClass* s = [[NSSomeClass alloc] init];
This is potentially problematic:
NSSomeClass* s = [NSSomeClass alloc]
[s init]; // bad! you ignored the result of init
The implementation of an init method must be done particularly carefully when the implementation returns a different object than the one it receives as the incoming 'self'. In such a case the init method takes on the responsibility of memory management of the 'self' object (because it's not going to return that object - so who else could be expected to do the management?)
It's possible to do some pretty ugly trickery, BTW. Don't try this at home!
// don't do this!
S* s = [S alloc]
[s retain]; // needs to survive 2 init's
S* ss = [s init......]; // s.retain goes 2-->1
S* sss = [s init.....]; // ... goes 1-->0;
Doing this is extremely poor practice because it depends on the init..... method always returning a new object (instead of the one it receives). That's an obviously bad assumption!
NOTE that by "a method receiving an object in 'self'" I mean that the method was invoked upon/by an object, and that object is made available by convention through the 'self' pointer.
The fundamental rule just doesn't apply in this special situation.
In fact, don't worry about it - unless you plan to do Posing, you won't need to write code that does this, and it will have no impact at all on the code you write.
You should continue to follow the fundamental rule in all your code.
And thirdly, the code is more what you'd call "guidelines" than actual rules.
(Captain Barbosa)
alloc/init is a bit of a special case. You have to do the retain/release stuff inside init in such a way that whatever object the caller gets back is owned by the caller and there are no leaks.

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.