Release NSMutableDictionary memory under ARC in iOS - ios

In my app, I used the NSMutableDictionary and when I go to a specific view controller, the memory utilized increases more.
How can I free the used memory in Objective-C?

All you need to do is assign it to nil. Under ARC that's all that's needed to 'release' an object:
self.myMutableDictionary = nil; //It no longer exists.
Note that this kills the reference that the view controller this code is run from has - if this is the only strong reference, then the object will be removed and the memory freed. If another object(s) have strong reference(s) pointing to the dictionary, though, then the memory won't be freed until those references are also set to nil. It's the responsibility of the allocating objects to be responsible and set their references to nil when they no longer need the object.

Related

Mark an object un-AutoRelease in ARC

As we all know, object will not dealloc immediately in ARC when no variable refer it. eg,
NSObject* obj = [[NSObject alloc] init];
obj = nil;
obj will dealloc after a time.(auto release pool drain).
Now, I want the obj dealloc right after it's been set to nil, which means the obj is not in auto-release-pool. But all other obj should work well as before, which means the program is still in ARC mode.
Is there a way, maybe macro or compiler flag, to do this?
First of all: You should not care about early deallocation. This is a strong code smell.
Second: Are you really, really sure, because -init does not put an object into ARP. Maybe the expression causes a retain autorelease combination, but compiling in release mode should optimize that away.
However, if it is in ARP you can close the ARP as mentioned by Hermann Klecker or – I think this is better – find the reason for being that object in ARP. There is no need for that.
Amin is right: the object is not in an autorelease pool. alloc, which created the object, does not engage a pool. On the other hand, you're right: ARC may not release the object immediately.
There is indeed an annotation you can use to force the release: objc_precise_lifetime. Adding that to the variable declaration will cause ARC to send release as soon as the object is no longer valid in the current scope.
However, Amin is also right that this is not very likely to be what you want. ARC knows what it's doing -- there are optimizations it can't make when you use this annotation -- and unless you know what it's doing too, you should strongly consider just letting it do its job.

Are objects immediately released when a property is allocated a second time?

I am working on an app where I am presenting 100 sentences using AVAudioplayer. Rather than have 100 AVAudioplayer objects I wanted to just have one property and change the object associated with it on the fly. My code boils down to the following (though the lines arent immediately following each other in the actual code):
self.thePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url1 error:&error];
self.thePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url2 error:&error];
Does the object initialized with url1 get released when thePlayer is allocated and initialized a second time with url2, or are both objects only released when the view is dismissed? As I am dealing with 100 sound files I don't want them all hanging around in memory. I'm using ARC
Thanks in advance
In your specific case, guessing at what your code likely includes, the objects will probably be deallocated when you want them to be. That's a lot of "guessing," "likely," and "probably." You really need to understand how the memory management works in order to reason about it.
If the AVAudioPlayer is strongly referenced by anything else, then it won't be released until those strong references are gone. In other words, setting thePlayer won't deallocate the player if something else has a strong reference to it. (That "something" may be some part of the system frameworks, or even itself in some rare cases. It doesn't have to be your code.)
If the AVAudioPlayer has pending autorelease calls on it, then it won't be released until the autorelease pool drains (usually at the end of event loop, which basically means "when your method that UIKit called returns.") For example, if you create a large number of objects in a loop and immediately throw them away, they may or may not be deallocated until the autorelease pool drains. Again, autoreleases may be injected by system frameworks. In practice, this means that the object will usually be deallocated "soon" (in a small fraction of a second), but not necessarily immediately. You can clean up autoreleased objects sooner by using #autoreleasepool blocks, which is sometimes necessary if you create many temporary objects in a loop. This is not needed very often.
But to a first-order approximation, in many of the most common cases, yes, replacing the property will automatically and immediately deallocate the previous object.
It would be useful to show how you declared thePlayer. If they are synthesized properly the memory management would be handled automatically. It appears that you are using "self" to access thePlayer and if so you'd be setting the value through a setter/getter and that would handle the memory management for you. But I also notice that "Self" is capitalized and should not be in order to properly use the setter/getter. For more info on synthesized variables check out: What exactly does #synthesize do?. Note there are some places where you should NOT use self and this link discusses that: How does an underscore in front of a variable in a cocoa objective-c class work?.

Keeping a strong pointer to a local object

I encountered this thing in a book which I am reading and it got me thinking:
"When you allocate a block, it is created on the stack. This means that, even if you were to keep a strong reference to it, calling it later would result in a crash because the memory would be destroyed as soon as you leave the method in which it was defined."
I thought if I have a strong pointer to something, it is kept alive?
Does this mean this does not apply for objects allocated on the stack?
I am trying to think of an example without using blocks...(e.g., of pointer - maybe an ivar- pointing to a stack allocated object which gets destroyed even though the pointer is alive)
Objects are never allocated on the stack in Objective-C. Blocks are special however, since they are stack allocated. So if you want to retain a pointer to a block, you must first copy it by using Block_copy and use the copy, then release it with Block_release. This must be done if the block is to be used after the scope it was declared in is destroyed. More on the matter here: https://developer.apple.com/library/mac/documentation/cocoa/Conceptual/Blocks/Articles/bxUsing.html (under "Copying Blocks"). Yet again though, this does not apply to regular objects.
Blocks can be messaged like objects. To move them from the stack to the heap, just "copy" them.
void (^stackBlock)() = [^(){
NSLog(#"Hello world");
} copy];

Objective-C memory management: when do you use `[variable release]` vs `variable = nil` to clean up memory?

I've people who use [variable release] and some other times variable = nil to clean up memory?
When do you use each one? and what are the differences?
variable = nil; will not release memory. self.property = nil; will release memory if [self setProperty:nil]; would, for example a synthesized property with the retain attribute. Calling [variable release]; will always release one reference of an object.
Depends on what you mean by "clean up memory".
release is the only thing that frees dynamically allocated memory allocated by alloc. alloc should always be paired with a call to release or autorelease somewhere.
Setting a varible to nil does not necessarily free any memory (see drawnonward's answer), and can be a source of memory leaks.
When you see a variable set to nil, it's about preventing it from accidentally being used later after its memory has been freed (this can cause crashes). While you can always set a variable to nil after a call to release, it's somewhat a matter of style when it's actually necessary. For example, you don't often see variables set to nil in the dealloc method of a class, since by that point an object won't be able to accidentally misuse such a variable anymore, since it's being nuked.
If a property is set to retain, then these 3 are equivalent:
[self setProperty:nil];
self.property = nil;
[property release]; property = nil;
In each case, the object will be released, and then set to nil so that all access to the object from then on will not be allowed. "nilling" the instance variable is handy since it ensures you can only ever release the object once in this context because calling self.property = nil twice will do nothing the second time, but calling [property release] will release the object twice even though you likely only retain it once.
Most of the time I find it least bug prone to let retain properties do their thing and try to stay away from explicit retain and release calls most of the time.

Ambiguous scenario for iPhone memory management

I have some difficulties to understand this scenario.
I create an object
I set its retained property to something
I forget to release its property
I release the object
As I didn't release the property in the dealloc method, will the scenario result in a memory leak or will the property be released automatically?
The way Cocoa works is that memory management always looks locally balanced, within any one method*. This is kind of the point. You should be able to tell whether you have a leak or error in a method just by looking at that one method. No global program knowledge required.
It is your responsibility to release an object if you received the object from a -copy, -alloc, -retain, or -new method.
If you do this:
[obj setProp:foo];
is it your responsibility to release foo? No - see rules. If obj retains it (and you're saying you happen to know that it does), then it is the responsibility of obj to release it, in its dealloc method if not sooner.
So if you did this, it's balanced, no matter what kind of property -prop is.
id obj = [[MyObject alloc] init];
[obj setProp:foo];
[obj release];
*except for within the implementations of init, copy, dealloc, and accessor methods.
Yes, it's leak.
Retain, alloc will increase the counter by one.
Release will decrease the counter.
It will free the memory when the counter reaches zero.
Think of setter as this:
[newvalue retain];
[property release];
property = newvalue;
So..
create an object => 0+1=1
assign it to some object as a retain property => 1+1=2
release the object => 2-1=1
You will have to release that object again sometime.
And, trust me autorelease doesn't work quite well in the iphone environment.

Resources