I'm currently profiling my app and coming across a few leaks. I've tried releasing objects all over the place where I think they are needed. Each release has crashed the app.
Here's one line that I think is the culprit:
NSDictionary *dicUserData = [NSDictionary dictionaryWithObject:self forKey:#"chapter"];
Just wondering the best way to deal with this. I'm having issues with other leaks too that are kind of similar. It's worth noting that self is a custom class [Dal_Chapter].
Do I need to implement copy or something, call that in the above line and do autorelease on that?
Thanks in advance.
Using convenience methods such as dictionaryWithObject provide an autoreleased instance of the dictionary object. Unless you're retaining it elsewhere this is not where your leak is.
I would check out the static analyser it should be able to point out your leaks for you.
That dictionary will retain self so you shouldn't have to worry about it.
Is the owner of self releasing it ?
Basicly you don't have to do anything whith your dictionnary, but if you want to take control of the memory you'll need to do this :
NSDictionary *dicUserData = [[NSDictionary alloc] initWithObjects:yourObject forKeys:key];
and int your dealloc method,
[dicUserDate release];
But normaly you just have nothing to do... Are you sure that your leak come from your dictionnary ?
always keep all variables release in dealloc method. is it not in proper place it may be crash .check this link click here
Related
I am writing a simple Obj-c app. So far I've never had to alloc anything and I gave for granted that ARC would take care of memory management.
But now I have to call:
NSImage *myImage = [[NSImage alloc] initByReferencingFile: pathToMyImg];
After I'm done with myImage should I manually dealloc it?
If you’re using Objective-C ARC (which is the default, and you said you were anyway), there is no difference in required memory management between factory method-style instantiation and [[NSImage alloc] init]-style instantiation. Everything you create will be automatically released when the last strong reference goes out of scope (or the object holding the reference’s last strong reference goes out of scope).
If you weren't using ARC, you’d have to manually do [myImage release] when you were done with it, but there’s no reason not to be unless you’re writing code for an older project.
After I'm done with myImage should I manually dealloc it?
The question makes no sense. You are using ARC. Suppose the answer were Yes. How would you do it? You cannot. ARC will not let you give any NSObject memory management commands.
Therefore the answer must be No.
I am pretty much a newbie to objective-c and as I started to program, I did not really grasp how to properly release objects. So, my project being an introduction into the world of Objective-c, I omitted it completely. Now, however, I think this project evolved in that it is too much of a pity to just leave it at that. So, all the allocs, copys and news aside, I have serious problems with understanding why my project is still leaking so much memory.
I have made use of the leaks tool in Instruments (look at screenshot), and it shows me that whole array of objects that are leaked. My question now: Is this something to be worried about, or are these objects released at some point ? If not, how do I find the cause of the leak ? I know that if I press cmd + e it shows me the extended detail window, but which of these methods should I look in ? I assume that it is my own methods I have to open up, but most of the times it says that i.e. the allocation and initialization of a layer causes the problem.
That said, I would like to know how to effectively detect leaks. When I look at the leaks bar of instruments, at the initialization of my game layer (HelloWorldLayer) a biiiig red line appears. However, this is only at it's initialization... So, do I have to worry about this ?
Here is the screenshot:
link to file (in order to enlarge) -> http://i.stack.imgur.com/QXgc3.jpg
EDIT:
I solved a couple of leaks, but now I have another leak that I don't quite understand :
for (int i = 1; i<=18; i++) {
NSMutableDictionary *statsCopy = (NSMutableDictionary *)CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFDictionaryRef)stats, kCFPropertyListMutableContainers);
NSNumber *setDone = [num copy];
[levels setObject:statsCopy forKey:[NSString stringWithFormat:#"level%d", i]];
[levels setObject:setDone forKey:#"setDone"];
[statsCopy release];
[setDone release];
}
He happens to detect a leak with the deep copy, even though I release it...
The screenshot shows that there's a dictionary allocated in -[Categories init] that never gets released. Actually, there are many (2765) such dictionaries.
That method seems to be invoking -[NSDictionary newWithContentsOf:immutable:]. The stack trace here may be somewhat misleading due to optimizations internal to Cocoa. That's not a public method. It's probably called by another NSDictionary method with a tail call which got optimized to a jump rather than a subroutine call.
Assuming there's debug information available, Instruments should show you the precise line within -[Categories init] if you double-click that line in the stack trace.
Knowing where it is allocated is not the whole story. The Categories class may manage ownership of the object correctly. Some other class may get access to it, though, and over-retain or under-release it. So, you may have to track the whole history of retains and releases for one of those objects to see which class took ownership and neglected to release it. Note, this has to be done for one of the leaked dictionaries, not one of the malloc blocks that was used internally to the dictionaries. Go down two lines in the table for some promising candidates. Toggle open that line to see the specific objects. Double-click one or click the circled-arrow button next to its address (I forget which) to see the history of retains and releases.
I am getting a bit confused. I am creating an app with storyboard, and running it on iPad 1. the application uses a lot of memory, so reached the 120mb, crashes. accordingly to what I have understood to remove this problem you need to release, dealloc... the point is that with ARC this should be automatic. In fact if I add for e.g.: [label1 release]; it gives me an error. But this ARC automatic release and dealloc does not seem to work! Is this because there are different ways to release with ARC??
You don't need to manually retain/release/autorelease with ARC. However if you have active references to a lot of unused objects they will still remain in memory. Profile your app with Instruments and it will show you how many objects you're creating of each class and how much memory they're consuming.
With ARC you still need to think about memory usage you just don't need to worry as much about memory leaks.
NSObject *bigMemObj = [[BigMemClass alloc] init];
//This creates the object in memory. In both arc and manual counting the retain count is 1
//Do stuff
//Prior to ARC you would have had to call [bigMemObj release]; before setting the variable to nil
bigMemObj = nil
//With ARC you don't have to do anything. The compiler inserts the release at compile time
Also read the documentation on declaring iVars __strong vs __weak.
Without looking at your code it's hard to identify what is consuming all the memory but hopefully that should help you determine where to start looking.
You should implement #autoreleasePool{} inside each method. In essence, each method will look like the following:
-(void)methodName{
#autoreleasePool{
//do method stuff
}
}
This will ensure that, upon exiting the autoreleasePool, memory is properly released.
I can't vote this back up, otherwise I would. I think Alessandro is asking about ARC vs using release and dealloc, not about what he's loading!
So, Alessandro, your understanding is correct that with ARC you don't release or dealloc. Therefore, those won't work if you're using ARC. Also, there is no alternative to release/dealloc, since ARC doesn't use it.
My suggestion would be to look at what you're using in the app that is taking up all this memory. Do you have a large number of pictures, for example, that are very large? Keep any graphics as small as possible, matching the resolution of the iPad. Especially the iPad 1, which doesn't have the "retina display".
You can use Autorelease pools in ARC. Here is some documentation on when to use them:
NSAutoreleasePool Class Reference
Advanced Memory Management Programming Guide: About Memory Management
Here is some code I have in my app that I DIDNT release. When I try to release I get a Program received signal: “EXC_BAD_ACCESS”. exception and the app crashes. If I dont try to release it the app runs fine.
Do I need to call a release message on these objects? Any idea what could be going on here?
NSString *sA = legA.text;
NSArray *firstLeg = [sA componentsSeparatedByString:#","];
[sA release]; //works ok
[firstLeg release]; //sends the bad access exception and crashes the app
Both of them don't need to be -released.
I suggest you read the Memory Management Rules. You need to -release an object if and only if the current scope is an owner of that object. You become an owner only when the object is received as
[[Foo alloc...] init...]
[foo new...]
[foo copy...] or [foo mutableCopy...]
[foo retain]
in all other cases, you should never -release it. As .text and -componentsSeparatedByString: are not one of these methods, there's no need to -release sA and firstLeg.
I'm not great at objective c, but shouldn't there be a [[NSArray alloc] init] thing somewhere? Or does the componentsSeperatedBySTring replace it?
No, you may only send release to objects you have ownership off: those you get from alloc/init, retain or copy.
Run, don't walk, to the "Object Ownership" section of the Memory Management Programming Guide for Cocoa and read up on the rules for when you "own" an object. You only release objects you own, so in this case you don't want to release them.
Several correct answers so far, but nobody has yet posted the Cocoa Memory Management Rules which should be compulsory when answering a "do I own this" question..
Edit: must type faster...
I am writing an Objective-C program that utilizes the garbage collector.
I am getting EXC_BAD_ACCESS in some situations, the classic example of an object being "over freed". Using some of the debugging tips in this technote, namely MallocScribble and AUTO_LOG_COLLECTIONS, I can see that my object is being GC'd out from under me.
With that said, here is my code.
I have an NSMutableDictionary that holds the ONLY reference to an object. In a method, I am then doing:
NSObject *object = [dictionary objectForKey:key];
NSLog(#"Object is %#", object);
[dictionary removeObjectForKey:key];
If I remove the object from the dictionary before the NSLog statement, if the GC runs at the right moment, I get the EXC_BAD_ACCESS. Removing from the dictionary after never fails.
Why is this?
The Garbage Collection Programming Guide section on interior pointers seems to be the closest documentation for this phenomenon, but it doesn't seem to quite fit. Try to verify that your app is actually using garbage collection instead of manual reference counting. If the garbage collector is really enabled, then it would seem that it either has a bug or an insufficiently-documented feature.
Have you verified that the garbage collection is truly on? You could try putting in a -dealloc method in your class and see if you ever hit it. It will never hit with GC on. According to Apple docs the GC should not collect objects pointed to by stack variables so what you're seeing should not happen.