Nasty NSPropertyListSerialization Leak - iphone

NSString *anError = nil;
id plist;
plist = [NSPropertyListSerialization propertyListFromData:rawCourseArray mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&anError];
if (anError != nil){
[anError release];
}
The above code causes a memory leak every time I call it. I am releasing the error but still there is a leak. I haven't seen any resolution to this issue. I posted this already and most respond that this is not a leak. But see here in the leak performance tool:
I need this fixed because eventually my app crashes. Any ideas? Many thanks

I had the same problem. Used propertyListWithData:options:format:error: with same result. Used NSDictionary initWithContentsOfFile with same result:
Leaked Object # Address Size Responsible Library Responsible Frame
NSCFNumber,19 < multiple > 304 Bytes MediaToolbox FigRemote_CreatePropertyListFromBinaryPListData
FWIW - I only have dictionaries and arrays and strings in the pList, no numbers.
The issue is not the error object (or string in your method). The issue is not plist above, since it should be autorelease. In the end, I gave up and reimplemented using JSON and:
http://stig.github.com/json-framework/api/index.html
==> no more leak.
Best,
Fred

I've had the same problem before.
Basically this is because your error variable got released without initiating it. So what you can do is try to init your NSString *error to an empty string before releasing it. Or not releasing it at all.

Related

exc bad access iphone error

I am getting an error called Thread 1: Program recieved signal:"EXC_BAD_ACCESS"
here is my code
[gameArray removeLastObject];
[gameArray addObject:shotArray];
[gamesArray removeObjectAtIndex:gameNumber];
[gamesArray insertObject:gameArray atIndex:gameNumber];
NSString *path = [self findGamesPath];
[NSKeyedArchiver archiveRootObject:gamesArray toFile:path]; // the error is here
Why is there an error? Is something being released too many times?
Here is the findGamesPath code
-(NSString *)findGamesPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentFolder = [paths objectAtIndex:0];
NSString *result = [documentFolder stringByAppendingPathComponent:#"iShotTrackGames.plist"];
return result; }
More likely than not, something is being released too many times. Turn on zombie detection and try again.
Before you do that, though, try performing a "Build and Analyze" on your code and fix any problems it identifies.
I see this is tagged with "thread-safety". Why? I.e. what are other threads potentially doing while the above code is running?
EXC_BAD_ACCESS means you've got a bad pointer somewhere. These errors are often pretty easy to spot because the bad pointer is one of the parameters to the method called on the line where the error occurs. In this case, though, the archiver is going to walk the entire object graph pointed to by gamesArray, and the bad pointer could really be anywhere in there. Follow #bbum's advice to turn on NSZombies -- that'll help you figure out which pointer is the problem.
I think I know what's happening. Your path string is losing scope inside the findGamePath method.
Are you allocating the path string inside that method and returning it?
Once it loses scope it's released from memory.
Trying to access that string then will cause EXC_BAD_ACCESS as you're accessing a released object.
Could you post the findGamePath code here? That may clarify the issue more.
Oh and this has more to do with memory management than thread safety.

Memory leaks caused due to CoreFoundation Framework

I am developing an iPhone application which mainly makes use of the Address Book and database. After fetching about 3000 contacts from the address book, I am attaching string tags to the contacts (5 for each). I am saving my tags in the database.
For Load testing purpose i have added 10,000 tags to the App. But during the load testing of my application, I observed some memory leaks which were not related to the Application code but represents a set of Instruction sets. Also Instruments showed Foundation as the responsible library for the Leak (Extensive use of NSString,NSDictionary,NSArray which belongs to the Foundation framework). My application crashes after 10 - 15 mins of usage.The Crash report mentions, application crashed due to low memory.
Memory profiling using CLANG shows zero leaks. How do i solve these memory leaks?
Are these leaks the real culprit behind the crash? Are there any other tools available to check memory leaks?
I often find my leaks say they're caused by Core Foundation (or any other framework for that matter) but are really my own. With the exception of the Simulator, rarely will you find excessive leaking in the frameworks.
If you open up the detail panel to the right in Instruments you may find listed your App's methods in there. That will give you indication of where it could be coming from in your code. One leak can spring many other leaks, and you may have to find the top level culprit to get rid of the lower level ones.
You should not expect Clang to do anything but find the most obvious leaks. It's very handy, but that's it, just a helpful addition to compiling.
clang is not a leak checker. It only detects a small subset of issues.
For memory leak debugging you should focus on Instruments, specifically the Object Allocation and Leaks instruments. Be sure to understand the difference between leaks and other source of high memory usage though.
Once you've determined that objects are leaking, use Instruments to examine their allocation stack trace (so you can tell what object it is), and their retain/release history.
If it's not a leak, then I suggest investigating the instructions here:http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/
Most likely you have code that is creating the foundation objects. Leaks shows you the place of allocation but that is generally due to a call your code made to create the object. You can look at the call chain in Instruments and go back along the call chain until you get to your code - that is the place where you are causing the allocation. Now, for that allocation, look at your memory handling for that object: Do you release it some time later?
There are lots of ways you can fail to release memory property so it would be hard to guess which one you might be hitting. Ones I see when helping people include allocating an object and assigning it to an instance variable via a property with the retain attribute, something like this:
#property (retain) NSString* myString;
...
self.myString = [[NSString alloc] initWithString: #"foo"];
the alloc+init creates a retained object, the self.myString = increments the retain count again. If coded correctly, the dealloc method releases the property via one of:
[myString release];
or
self.myString = nil;
And that takes care of the retain added with the self.myString = but does NOT take care of the retain from creation. Solutions, ONE of the following:
myString = [[NSString alloc] initWithString: #"foo"]; // doesn't call the setter method so no assignment retain - but doesn't call the setter which might be bad if non-trivial setter.
self.myString = [[[NSString alloc] initWithString: #"foo"] autorelease];
autorelease releases the alloc+init retain.
Now of course this is a contrived example because you'd probably really use:
self.myString = [NSString stringWithString: #"foo"];
which is a class method returning an autoreleased string and avoids the problem. But the idea is to show a simple example to explain this type of issue.
There are many other ways to not release memory properly, but the advice to work your way back up the call-chain until you get to your code is the way to go look at where you are triggering the allocation of the memory and then you can figure out why you aren't releasing that properly.
Try to do some issues in u code:
1. Please avoid hide declaration like
NSString *string = [dictionary valueForKey:[dictionary2 valueForKey:#"something"]]
Correct code is:
NSString *key = [dictionary2 valueForKey:#"something"];
NSString *string = [dictionary valueForKey:key];
key = nil;
Try to avoid declaration with autorelease and local declaration like:
NSArray *array = [NSArray array];
If u do this, make sure that u have:
NSArray *array = [NSArray array];
.... some code where array is using;
array = nil;
Better idea is alloc and release immediately when u don't need object and put it to nil.
3. Check if u using correct setters. Probably better idea is avoid to using it, at my experience, deallocate class start leaks for getters and setters, which was using before.
If u post some part of u code, where u seen most leaks (instruments give u possibility to click on leaked objects and see volume of leaks in programming code) community can suggest more.

Memory Leak in Propertylist Serialization

Now it's time for me to ask a question. Until now I just ignored that Memory Leak. But now it's to find out which object leads to this leak.
I have the following code:
NSDictionary *addressDic = [[NSDictionary alloc] initWithDictionary:[NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&anError]];
At a later Point I also release the addressDic.
If I use Instruments to detect Memory Leaks I get one at above posted code. I'm leaking about 16 Bytes and the objecttype is NSCFString. Why?
I hope you can help me.
Sandro
You need to -release the anError variable if there is an error.

Leak in managedObjectContext save:

I have the following piece of code and when I use Instruments/Object Allocations, it tells me that there is a leak there (which goes down to sqlite3MemMalloc). Is there something that I should release?
if (![managedObjectContext save:&error]) {
NSLog(#"Error while saving.");
}
The save works well and doesn't trigger an error.
The leak is most likely in one of the managed objects being saved and it just shows here. If you look at the stack in Instruments you can probably see the leaking object. Since it only shows up at save, it's probably in validation code.
Do you have any subclasses of your NSManagedObject instances?
When you set a value into your NSManagedObject instances do you then release your ownership of them? For example if you were do to the following code:
NSString *someString = [[NSString alloc] initWithString:#"Blah"];
[myManagedObject setValue:someString forKey:#"stringValue"];
You would be leaking memory because you are still owning that NSString. That is what TechZen is referring to above.

stringWithContentsOfURL leaking memory

Would it shed more light if I told that fetchHTML was being called in a seperate thread? I am also seeing several messages in the debug console such as:
_NSAutoreleaseNoPool(): Object 0xd92860 of class NSCFDictionary autoreleased with no pool in place - just leaking
_NSAutoreleaseNoPool(): Object 0xd92800 of class NSCFString autoreleased with no pool in place - just leaking
I am new to iPhone app development, Objective-C but not new to programming or C/C++. I am using the leaks performance tool and it shows many leaks. This is a 10.5 kb leak and it occurs on the line:
NSString * xml = [NSString stringWithContentsOfURL:urlobj];
The stack trace on this below is:
stringWithContentsOfURL
initWithContentsOfURL
initWithDataOfEncoding
...
Does anyone have an idea why this must be happening. I am under the impression that I get an autorelease object here and I can return this to the caller without calling retain. I am not using the xml object to store in an instance variable, just for processing.
Here is the function code:
- (NSString *) fetchHTML: (NSString* ) url{
#try
{
NSURL* urlobj = [NSURL URLWithString:url];
NSString * xml = [NSString stringWithContentsOfURL:urlobj];
return xml;
}
#catch( NSException *ex){
NSLog(#"Error fetchingHTML");
return nil;
}
return nil;
}
Yup; that shouldn't be leaking.
It might be a false positive in that the URL subsystem is caching the contents of the URL and doing so in a way where the pointer is no longer visible to leaks analysis.
If you can, retry the test on Snow Leopard. Leaks detection on Snow Leopard is significantly faster and more accurate.
I completely agree with you that this should not cause a leak. I've been coding in Cocoa/Objective-C for 2 years now, and that looks like it should work.
That being said, I notice that Apple's documentation indicates that the stringWithContentsOfURL: method is being deprecated. Perhaps it would work as follows:
NSString * xml = [[NSString alloc]
initWithContentsOfURL:urlobj
encoding:NSASCIIStringEncoding
error:nil];
return [xml autorelease];
As the error message says, there's no autorelease pool for the string to go into, and that creates a leak. NSAutoreleasePools exist on a per-thread basis. Cocoa creates one in the main event loop of the main thread, but that's the only one it creates for you. If you're somewhere other than the main thread and you're going to be dealing with autoreleased objects, you need to create an autorelease pool for that thread as well.
You can check out the NSAutoreleasePool docs for more information on how autorelease pool stacks work.