iOS Memory leaks - objective-c

I have read that dealloc for an object will be called, only if retain count of that object becomes zero.
I am taking one object for UIColor in interface section and setting property
UIColor *currentColor;
#property (nonatomic, retain) UIColor *currentColor;
After using this object in the implemetation section, I am calling release method for this object in dealloc
-(void)dealloc
{
[currentColor release];
[super dealloc];
}
I am in doubt how dealloc will be called for this object, because I am not releasing the retained object anywhere. Thanks in advance.

I have read that dealloc for an object will be called, only if retain
count of that object becomes zero.
Yes.
For the sake of simplicity, call the class that contains currentColor object as ColorContainer. Now, if you create an instance of ColorContainer like the following:
ColorContainer* containerColor = [[ColorContainer alloc] init]; // retain count + 1
the retain count for containerColor becomes 1.
Suppose you create an instance of a UIColor and you set that instance to currentColor property. In this case you can follow two different ways.
In the first one you can create an instance like the following. If you use an instance method like initWithRed:green:blue:alpha: you have to release memory explicitly.
UIColor color* = [[UIColor alloc] initWithRed:0 green:0 blue:0 alpha:1]; // retain count + 1
containerColor.currentColor = color; // retain count +1, the referenced object has a retain count of 2 because you use a retain policy
[color release]; // retain count -1, now the referenced object has a retain count of 1
In the second way, instead, you could use a class method (+ symbol). In this case you don't need to release memory explicity because the object created in that class method will be autoreleased at a certain point of your application lifetime.
containerColor.currentColor = [UIColor whiteColor]; // retain count +1
Now suppose you release containerColor object. If the retain count for containerColor is equal to 1, releasing it from an object that uses it, it enables to call its dealloc method and, in consequence, to dismiss also the object referenced by currentColor.
In this simple case study you have to note that the object referenced by currentColor is completely removed from memory (dismissed) only if it has a retain count of 1. In fact, if you do this
UIColor color* = [[UIColor alloc] initWithRed:0 green:0 blue:0 alpha:1]; // retain count + 1
containerColor.currentColor = color; // retain count +1, the referenced object has a retain count of 2
//[color release];
you create a memory leak (Do you understand way?).
To summarize, when you use retain, copy, init or new (it's the same of alloc-init), you have always to call their counterparts release or autorelease.
As a rule of thumb, you need always to balance the retain count for objects to avoid memory leaks.
So, as a methaphor you could think to memory like a tree. Suppose you have a parent (containerColor) and a child (currentColor). If the parent (with a retain of count of 1) is released, it causes to call its dealloc method and free memory for its object. If in its dealloc method you release a child (with a retain count of 1) it causes to call its dealloc method and free memory. In the case a child has a retain count greater than one, you cause a memory leak.
Hope it helps.
Edit
For further information you could read About Memory Management. Since iOS 5 Apple has introduced ARC. Automatic Reference Counting is a compiler machanism that provides automatic memory management of Objective-C objects. For info see Transitioning to ARC Release Notes.

When you use retain setter for currentColor property you retain that object, and if you retain , copy or alloc memory for a object you MUST RELEASE IT. -(void)dealloc is the best place to do it

You should only call release on the object if you allocated it (via alloc, copy or retain). Properties with the retain attribute will automatically do the memory management for you as long as you handle them properly, e.g. only access them via self.currentColor. Depending on how you created the color object you might or might not use release but you always should set the property to nil in your dealloc method. Two examples:
// If you use this (or some other way to get the color without alloc, copy or retain)
// then you do not need to do any release
self.currentColor = UIColor.blackColor;
self.currentColor = [UIColor colorWithRed:1.0 green:0.5 blue:0.2 alpha:1.0];
// On the other hand if you get it like this, you have to release/autorelease the object
self.currentColor = [[UIColor alloc] initWithRed:1.0 green:0.5 blue:0.2 alpha:1.0];
[self.currentColor release];
// or better
self.currentColor = [[[UIColor alloc] initWithRed:1.0 green:0.5 blue:0.2 alpha:1.0] autorelease];
// dealloc always the same
-(void)dealloc{
[currentColor release], currentColor = nil;
[super dealloc];
}
There are two important facts here:
For each alloc, copy or retain that your code issues, you have to issue release or autorelease.
Always use self.currentColor to access the property and not currentColor except when deallocating. The thing here is that when using self.currentColor the system automatically adds memory management code. Whenever self.currentColor is set, it automatically retains and releases the objects. Only on final deallocation you should set the variable directly, for more information see this answer on the topic (thanks to Flex_Addicted).

Related

arc, strong and weak instance variables

Just trying to fully understand ARC.
MyView *testView = [[MyView alloc] init];
__weak MyView *weakView = testView;
[weakView addObserver:self forKeyPath:#"alpha" options:0 context:nil];
testView = nil;
if(weakView) {
NSLog(#"WeakView exists!");
}
I don't understand why my NSLog statement is printing. Since weakView is a weak reference to testView, shouldn't it be pointing to nil once testView is set to nil???
Thanks!
The addObserver method seems to retain and autorelease the view. Thats why the weak reference is not zeroed right after the initial reference is nilled. Just run this code in the debugger:
UIView *testView = [[UIView alloc] init];
__weak UIView *weakView = testView;
#autoreleasepool {
[weakView addObserver:self forKeyPath:#"alpha" options:0 context:nil];
}
testView = nil;
if(weakView) {
NSLog(#"WeakView exists!");
}
It may or may not. It goes to nil when the object is deallocated. The fact that you set testView to nil only implies that you are releasing the object. But the object is not guaranteed to immediately be deallocated.
The problem here is that you are assuming a given value for the retain count. You think that the alloc+init sequence gave you an object with a count of 1 so that when you set testView to nil it goes to 0 and the object is deallocated.
You should never assume a given retain count. You should always think in terms of relative retain counts. The alloc+init sequence returns a +1 object (not 1 but +1). When you set set testView to nil ARC calls release and turns it to a +0 object (not 0, but +0). This means you have no guarantee that it's still accessible. Your weak reference may or may not be valid.
What is in fact happening is that internally in the init method (or the chained init methods of the parents) there has been a call to autorelease therefore your object does not yet have a refcount of 0. It will get it (and be deallocated) at the next pool drain.
Edit:
Also what Adam says in his reply is correct.
Your testView is local variable and local variables under ARC doesn't have precise lifetime semantics. Read 6.1 at:
http://clang.llvm.org/docs/AutomaticReferenceCounting.html#optimization.precise
What does it mean? This means that the compiler can do whatever it wants to do.
Current implementation releases testView object at the end of the method. But what if the optimizer (now, future, ...) decides that the lifetime is over and it will release it sooner (before the end of the method)?
In other words, you're trying to depend on undefined behavior. Don't do this, don't rely on this. In this case, you never know when the object is really released = weak reference is zeroed.

Managing Memory in Objective c

I am doing my project in xcode 4.2 (Older Version). For my application, I just set the variables, arrays in dto class for using in entire app lifecycle. so I set with a property like this.
AppDTO(sub class of NSObject)
AppDTO.h
#property(nonatomic,retain)anotherAppDTO *aAppDTO;
#property(nonatomic,retain)NSMutableArray *array1;
#property(nonatomic,retain)NSMutableArray *array2;
#property(nonatomic,retain)NSString *string1,*string2,*string3;
AppDTO.m
- (id)init
{
self = [super init];
if (self) {
self.aAppDTO = [[anotherAppDTO alloc]init];
self.array1 = [[NSMutableArray alloc]init];
self.array2 = [[NSMutableArray alloc]init];
self.string1 = #"Hello";
self.string2= #"Hai";
}
}
-(void)dealloc
{
if(array1 != nil)
{
[array1 release];
array1 = nil;
}
if(array2 != nil)
{
[array2 release];
array2 = nil;
}
[aAppDTO release];
aAppDTO = nil;
[super dealloc];
}
when I analyze my app in Xcode 4.3.2, I get memory warning in self.array1 and self.array2 (Potential leak on object allocated on line….), but when I change self.array1 to array1, warning goes away.
What is the reason for using self. do I need to use self if I set #property(nonatomic,retain) to variables(like array1,array2,string1,string2).
Also in dealloc method, I heard we don't want to use [self.array1 release], instead we can use [array1 release]. Is it Correct?
Do I need to release my string in dealloc method.
Also I am releasing aAppDTO in dealloc method. if I allocate some objects in anotherAppDTO class, will it release automatically when I call [aAppDTO release] method.
Can anyone clarify me.
Many Thanks,
Anish
You get the warning because when you write :
self.array1 = [[NSMutableArray alloc]init];
is the same as :
[self setArray1: [[NSMutableArray alloc]init]];
As you can notice you are not allocating the underlying array1 private variable, but you are calling the setter of the property that since it is declared as retain it retains the object once assigned, this means that when you eventually will assign another object the second time with the setter the first object will remain with a retain count of one until the application will be closed (since you don't have any reference to that object anymore ...) .
Take a look at this great article to understand better Manual Reference Counting in Objective-C .
when i analyze my app in Xcode 4.3.2, i get memory warning in self.array1 and self.array2 (Potential leak on object allocated on line….), but when i change self.array1 to array1, warning goes away.
the analyzer's right. the parameter is retained when set. as well, you should favor direct access in initialization and dealloc. so, you should just write array1 = [[NSMutableArray alloc] init];, and be done.
What is the reason for using self. do i need to use self if i set #property(nonatomic,retain) to variables(like array1,array2,string1,string2).
those go through the accessor methods. if not in initialization or dealloc, you should favor going through the accessor methods because that is the common correct execution path for a fully constructed object.
Also in dealloc method, i heard we don't want to use [self.array1 release], instead we can use [array1 release]. Is it Correct?
correct.
Do i need to release my string in dealloc method.
yes.
Also I am releasing aAppDTO in dealloc method. if i allocate some objects in anotherAppDTO class, will it release automatically when i call [aAppDTO release] method.
when its reference count reaches 0, its dealloc will be called.
I think the others have answered your question.
I do want to draw your attention to Apple's excellent Advance Memory Management Programming Guide: Practical Memory Management, in which they walk through these sorts of scenarios. It's hard to take it all in on the first reading, but it really does cover this stuff. In answer to your question about the use of instance variables versus the accessor methods, I draw your attention to the section labeled to "Don't Use Accessor Methods in Initializer Methods and dealloc".

Why do we have to set __block variable to nil?

From the Transitioning to ARC Release Notes
Use Lifetime Qualifiers to Avoid Strong Reference Cycles
You can use lifetime qualifiers to avoid strong reference cycles. For
example, typically if you have a graph of objects arranged in a
parent-child hierarchy and parents need to refer to their children and
vice versa, then you make the parent-to-child relationship strong and
the child-to-parent relationship weak. Other situations may be more
subtle, particularly when they involve block objects.
In manual reference counting mode, __block id x; has the effect of not
retaining x. In ARC mode, __block id x; defaults to retaining x (just
like all other values). To get the manual reference counting mode
behavior under ARC, you could use __unsafe_unretained __block id x;.
As the name __unsafe_unretained implies, however, having a
non-retained variable is dangerous (because it can dangle) and is
therefore discouraged. Two better options are to either use __weak (if
you don’t need to support iOS 4 or OS X v10.6), or set the __block
value to nil to break the retain cycle.
Okay, so what's different about __block variable?
Why set to nil here? Is __block variable retained twice? Who hold all the reference? The block? The heap? The stack? The thread? The what?
The following code fragment illustrates this issue using a pattern that is sometimes used in manual reference counting.
MyViewController *myController = [[MyViewController alloc] init…];
// ...
myController.completionHandler = ^(NSInteger result) {
[myController dismissViewControllerAnimated:YES completion:nil];
};
[self presentViewController:myController animated:YES completion:^{
[myController release];
}];
As described, instead, you can use a __block qualifier and set the myController variable to nil in the completion handler:
MyViewController * __block myController = [[MyViewController alloc] init…]; //Why use __block. my controller is not changed at all
// ...
myController.completionHandler = ^(NSInteger result) {
[myController dismissViewControllerAnimated:YES completion:nil];
myController = nil; //Why set to nil here? Is __block variable retained twice? Who hold all the reference? The block? The heap? The stack? The thread? The what?
};
Also why myController is not set to nil by compiler. Why do we have to do so? It seems that the compiler sort of know when myController will no longer be used again namely when the block expire.
When you have code of this form:
object.block = ^{
// reference object from inside the block
[object someMethodOrProperty];
};
object will retain or copy the block you give to it. But the block itself will also retain object because it is strongly referenced from within the block. This is a retain cycle. Even after the block has finished executing, the reference cycle still exists and neither the object nor the block can be deallocated. Remember that a block can be called multiple times, so it cannot just forget all the variables it references after it has finished executing once.
To break this cycle, you can define object to be a __block variable, which allows you to change its value from inside the block, e.g. changing it to nil to break the cycle:
__block id object = ...;
object.block = ^{
// reference object from inside the block
[object someMethodOrProperty];
object = nil;
// At this point, the block no longer retains object, so the cycle is broken
};
When we assign object to nil at the end of the block, the block will no longer retain object and the retain cycle is broken. This allows both objects to be deallocated.
One concrete example of this is with with NSOperation's completionBlock property. If you use the completionBlock to access an operation's result, you need to break the retain cycle that is created:
__block NSOperation *op = [self operationForProcessingSomeData];
op.completionBlock = ^{
// since we strongly reference op here, a retain cycle is created
[self operationFinishedWithData:op.processedData];
// break the retain cycle!
op = nil;
}
As the documentation describes, there are a number of other techniques you can also use to break these retain cycles. For example, you will need to use a different technique in non-ARC code than you would in ARC code.
I prefer this solution
typeof(self) __weak weakSelf = self;
self.rotationBlock = ^{
typeof (weakSelf) __strong self = weakSelf;
[self yourCodeThatReferenceSelf];
};
What happens is that the block will capture self as a weak reference and there will be no retain cycle. self inside the block is then redefined as __strong self = weakSelf before your code runs. This prevents self from being released while your block runs.

Why always leak when using CLLocationManager?

myclass.m
- (id) init {
self = [super init];
if (self != nil) {
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self; // send loc updates to myself
}
return self;
}
- (void)dealloc {
[locationManager release];
[super dealloc];
}
I use instrument to check leak. The leak always point to
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
Why?
I use instrument to check leak. The
leak always point to
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
Why?
Because that is the line of code where the allocation that is leaked occurred. Since you have balanced both implied retains in that code correctly (once here, once in -dealloc -- mmccomb's suggestion of direct assignment without autorelease is good, but won't fix the problem), the leak is elsewhere.
Specifically, the leak will be a retain that isn't balanced by a release. So, somewhere your are retaining the object and not releasing it.
Instruments can be used to show all retain/release events on any given object. Use that and look through the list of events related to your leaked object. There will be one more retain than release. Pair off the retains and releases. Whichever retain is left without a balanced release is the cause.
I wrote an article about using Heapshot analysis in Instruments to detect memory abuse. It includes discussion and screenshots showing the retain/release event inspector and will be applicable.
Try to avoid using the self. setter notation in init methods. When an object is being initialised there is no guarantee that it is in a consistent state. Change your implementation to directly set the ivar as follows...
locationManager = [[CLLocationManager alloc] init];
You no longer need the autorelease call which was previously accounting for the extra retain count brought about by invoking the setter. You do however need to release the object in your dealloc method (as you are already doing).
You can explicitly check the retain count in dealloc like so:
NSLog(#"locationManager retain count: %d", [locationManager retainCount]);
If it is more than 1, check where else you may be retaining it - like if you assign it to another retaining property (e.g. declared with retain keyword). You can add that NSLog call in other locations before and after you do something with locationManager and see where the retain count increases. Sometimes it may not be immediately obvious.
Another possibility: does the dealloc method even get called? Perhaps the whole "myclass" object is not properly released? (Although I suppose in that case you'd see a leak of type "myclass", too).

Objective-C ref count and autorelease

Hey guys, suppose the following code:
int main (int argc, const char * argv[])
{
//[...]
Rectangle* myRect = [[Rectangle alloc] init];
Vector2* newOrigin = [[[Vector2 alloc] init] autorelease]; // ref count 1
[newOrigin setX: 50.0f];
[myRect setOrigin: newOrigin]; // ref count 2
[myRect.origin setXY: 25.0f :100.0f]; // ref count goes to 3... why ?
[myRect release];
[pool drain];
return 0;
}
Rectangle's origin is declared as a (retain) synthesized property.
Just wondering 2 things:
Why does ref count goes to 3 when using the getter accessor of Rectangle's origin? Am I doing something wrong ?
With a ref count of 3, I don't understand how this snippet of code cannot leak. Calling release on myRect will make it go down to 2 since I call release on the origin in dealloc(). But then, when does autorelease take effect?
Thanks!
Why does ref count goes to 3 when
using the getter accessor of
Rectangle's origin?
Because your #property is declared as atomic (the default) and, thus, the synthesized getter retains and then autoreleases the return value.
Am I doing something wrong ?
Yes. You are studying absolute retain counts.
The absolute retain counts of any object is quite thoroughly useless to consider. You only care about deltas; if you cause the retain count to increase, you must cause it to decrease.
With a ref count of 3, I don't
understand how this snippet of code
cannot leak. Calling release on myRect
will make it go down to 2 since I call
release on the origin in dealloc().
But then, when does autorelease take
effect?
An autorelease is simply a delayed release that kicks in when the containing pool is drained. So, in your case, the object will be deallocated when [pool drain]; is executed.
From Apple's documentation on -retainCount:
Important: This method is typically of
no value in debugging memory
management issues. Because any number
of framework objects may have retained
an object in order to hold references
to it, while at the same time
autorelease pools may be holding any
number of deferred releases on an
object, it is very unlikely that you
can get useful information from this
method.