Memory management in Xcode - ios

I try to allocate and release a mutable array in Xcode
NSMutableArray *inventory = [[NSMutableArray alloc] init];
[inventory addObject:#"one"];
[inventory release];
Does anyone help me to explain why after "inventory" was released, it still store 1 objects?

Assuming you are working without Automatic Reference Counting (ARC):
When you release an object, that marks the memory that the object was previously occupying as free. However, it does not necessarily immediately destroy what was in that memory.
If you try to (improperly) access what was at your array's memory address, you may very well find the array members still there. But be warned, this is not safe, and the array and its members can (and will) be overwritten at any time.
You should use ARC for any production code to avoid the dangers of memory mismanagement. It works very well.

Related

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?.

Release NSMutableDictionary memory under ARC in 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.

Potential memory leak - Received Memory Warning

I am using iOS 7 and I am getting memory warnings in this part of code, but I'am not able to understand how the retain count increases as I release imageToSave variable too.
Static analyser not always write about memory leak but its assuming that when you are calling finalOutput its returning you an allocated object mean +1 retain count object which is never used and its treating this waring as memory leak!
You have not allocated memory to this object yourself, so you don't own it. And you are still releasing it.You can't release objects you don't own.
Unless you use alloc method to allocate memory, you can't just release them........

Guarantee a deallocation in ARC

I'm currently developing a game for iOS and we have a memory leak. Our project is ARC set up. I was wondering on how to ensure memory deallocation. One of the steps I was thinking of taking was convert code of the form:
-(void)methodMethod{
Object* o = [[Object alloc] init];
// Some logic
}
into:
-(void)methodMethod{
Object* o = [[Object alloc] init];
// Some logic
o = nil; // Explicit nil assignment
}
Is there a difference between the two? What other measures should I take to ensure a dealloc in an ARC setup?
We're using the Sparrow Framework.
Both methods do the same thing. Local objects are set to nil by ARC when they leave scope, so putting in a manual nil does nothing.
If you want to find a leak - you are far better off actually running it through Instruments with the Leaks tool and finding out what is being leaked, which will give you a better idea of what is going on. It's quite handy for finding retain-cycles.
As pointed out by Abizem, both methods lead to the same results, and require careful passes through Instruments. The results are not always easy to interpret.
In ARC, you should never see a leak - in the usual obj-C meaning -. Sometimes, iOS instruments can report a leak, but most if not all, this comes from the runtime, and I tend to regard them as beyond my control. What you can see however, is uncontrolled memory increase, which is typical of memory retention. Keeping strong pointers on objects is the obvious reason, which in my case has always been the consequence of : retain cycles in code blocks, and incorrect data structure cleanup, i.e. objects are created, then filled into arrays, dictionary, page control etc... but the later were not emptied properly during the app lifecycle.
Also image processing functions still use standard malloc/free directives embedded into internals UIGraphics lib, so in that case you explicitly need to free the memory (CGImageRelease, etc...). ARC will not help here.
hope this helps narrow down the problem, which as Abizem pointed out, should start with Instruments.
the following is unnecessary but (at least for me) the discussion in the comments was helpful and that's why I leave it
wrap the method in an #autoreleasepool. that will make it 99% percent sure it is being deallocated
-(void)methodMethod{
#autoreleasepool {
Object* o = [[Object alloc] init];
// Some logic
}
}
Both are the same.
A better solution to test your class:
- (void)testDealloc
{
__weak CLASS *weakReference;
#autoreleasepool {
CLASS *reference = [[CLASS alloc] init]; // or similar instance creator.
weakReference = reference;
// Test your magic here.
[...]
}
// At this point the everything is working fine, the weak reference must be nil.
XCTAssertNil(weakReference);
}
This works creating an instance to the class we want to deallocate inside #autorealase, that will be released (if we are not leaking) as soon as we exit the block. weakReference will hold the reference to the instance without retaining it, that will be set to nil.

iOS - Problems with memory and retain/release

I had developed an app and now I'm using Instruments to see the memory usage. I have a problem understanding the retain/release process of my object. This is what Instruments says:
The retain count increase when I add my object into an array, when I add it on my view and when I take off from the array.
So, when I use removeFromSuperview the object retainCount will never be zero, so the object don't release the memory.
EDIT 1:
I forgot to say i'm using ARC.
EDIT 2:
I describe exactly what happen :
I create the object together other objects in a class called NKLevelGenerator. Into it i alloc the NKIngredients and then i add all to a NSArray which will be returned. Here the retain count of every object is 2. In my NKLevelVC, my ViewController, i use this instruction :
[level addObjectsFromArray:[levelGenerator level1WithDelegate:self ciotola:ciotola bagliore:bagliore difficulty:NKDifficultyHard]];
Object level is a NSMutableArray that i alloc and init in viewDidLoad.
From here i call another method which performs this operations :
- (void)insertInArrayRandomly {
for (int i=0; i<[level count]; i++) {
[ingredienti insertObject:[level objectAtIndex:[[indexes objectAtIndex:i]integerValue]] atIndex:i];
}
}
Object ingredienti is another NSMutableArray that I alloc and init in viewDidLoad. indexes is an array of NSInteger which contains random indexes to extract NKIngredient object randomly.
Then i'm doing this :
NKIngredient *ing = [ingredienti objectAtIndex:index];
[[self view] insertSubview:ing belowSubview:navBar];
[ing animateIngredient];
[ingredienti removeObject:ing];
Before looking into Instruments have you tried the Static Analysis of your code? It may help for simple memory problems.
But the very first thing to check is: Did you follow the Golden Rule?
The Golden Rule being: For each alloc, copy or retain you must use one, and only one, releaseor autorelease.
This is the most important rule for memory management without ARC. So the fact that you object is retained by th array is none of your business, just remember what you have retained, allocated or copied and release it.
PS: Next time, your code would be much more helpful than the Instruments screenshot.
First: use instruments to see if effectively there's a memory leak, there's a tool made for this purpose and it tells you where you leak memory.
Second: it depend on how many object made [retain] on the view. If you add to an Array, it retain the view, but if you don't release it in the method that create the view, when you release the view from the array, the count will still be 1.

Resources