Help with Memory leak: init NSMutableArray from file - iphone

In some point in my app, I need to load a list from a file, so I implement this method to load the list:
-(void)loadList
{
NSString *filePath = [self dataFilePath]; //This is a method return the path of file
if([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSMutableArray *tempArray = [[NSMutableArray alloc]initWithContentsOfFile:filePath];
self.list = [[NSMutableArray alloc]initWithArray:tempArray];
[tempArray release];
}
}
The self.list is a (retain) property.
I think the leak is from [alloc] when I init the selfl.list. I used
self.list = [[[NSMutableArray alloc]initWithArray:tempArray]autorelease];
But the app crashes due to EXC_BAD_ACCESS. So I am confused here how to solve this.
Thanks for any suggestions.

Just assign,
self.list = tempArray;
As tempArray is already an array, you don't have to create another array from it. You ca directly assign to self.list.

There is no need to allocate another time for array .So just assign directly
-(void)loadList
{
NSString *filePath = [self dataFilePath]; //This is a method return the path of file
if([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSMutableArray *tempArray = [[NSMutableArray alloc]initWithContentsOfFile:filePath];
self.list = [tempArray copy];
[tempArray release];
}
}

Don't autorelease it. (I guess).

is your list property assign or retain?
if it is retain, then you should change this:
self.list = [[NSMutableArray alloc]initWithArray:tempArray];
to this:
self.list = [[NSMutableArray arrayWithArray:tempArray];

Related

Instance Variable not allocating in memory

I'm having an NSObject class where i have an init method defined something like below,
- (id)initWithPlistName:(NSString *)plistFileName{
if (self = [super init]) {
plistName = plistFileName;
plistContent = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:plistName ofType:#"plist"]]; // this plistContent array is not allocating in memory
}
return self;
}
I'm calling this method in my applications AppDelegate Class didFinishLaunchingWithOptions method, plistContent is my iVar of type NSArray but whenever control comes to plistContent alloc init line and while returning self, there is no memory allocated for my array.
What may be the problem happening here, Any help is appreciated in advance.
I suppose you have not changed the Datatype of your plist root key in your plist flie from dictionary to array
Check file exists:
NSString *path = [[NSBundle mainBundle] pathForResource:plistName ofType:#"plist"];
if(path)
{
plistContent = [[NSArray alloc] initWithContentsOfFile:path];
}
else
{
NSLog(#"File Not exists");
}
Try this
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"plistName" ofType:#"plist"];
NSDictionary *myDict = [[NSDictionary alloc] initWithContentsOfFile:filePath];
NSArray *array = [NSArray arrayWithArray:[myDict objectForKey:#"Root"]];

NSCFString countByEnumeratingWithState:objects:count: ERROR while searching NSMutableArray

I have the following situation where
I have an NSMutableArray filled with an xml file which I want to search.
When I enter something in the search field I get this Error:
-[NSCFString countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0x5b388b0
What does it means and how can I fix it??
I suppose the error is somewhere around here.
- (void)searchTableView{
searchedList = [[NSMutableArray alloc] init];
NSLog(#"new list %#", searchedList);
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in list) {
NSArray *array = [dictionary objectForKey:#"TITLE"];
[searchArray addObjectsFromArray:array];
}
for (NSString *TempArray in searchArray) {
NSRange titleResults = [TempArray rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResults.length > 0)
[searchedList addObject:TempArray];
}
[searchArray release];
searchArray = nil;
}
it means you are calling a method designed for an NSArray (countByEnumeratingWithState:objects:count on a NSString.
I don't know ifthis code is copy/paste from yours, but if so, at the end where you use [searchList addObject:TempArray] you don't have an object named searchList.
Also, work on your naming conventions. big time.

Instruments Leaks tells about a memory leak when initializing object

Can anyone please tell me why the following code leaks? Instruments tells me about 2 leaks. The 2 lines that obviously cause the leak are:
Person *pers = [[Person alloc] init];
and
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
The whole is listed below:
PersonViewController *personenDatenController = [[PersonViewController alloc]
initWithStyle:UITableViewStyleGrouped];
personenDatenController.view.backgroundColor = [UIColor clearColor];
Person *pers = [[Person alloc] init];
NSString *path = [[self class] pathForDocumentWithName:#"Person.plist"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:path];
if (!fileExists) {
NSLog(#"file does not exist yet");
NSString *content = #"";
NSData *fileContents = [content dataUsingEncoding:NSUTF8StringEncoding];
[[NSFileManager defaultManager] createFileAtPath:path
contents:fileContents
attributes:nil];
}
NSMutableDictionary *dict = [[NSMutableDictionary alloc]
initWithContentsOfFile:path];
[pers setVorName:[dict valueForKey:#"vorName"]];
[pers setNachName:[dict valueForKey:#"nachName"]];
[pers setStrassenName:[dict valueForKey:#"strassenName"]];
[pers setHausNummer:[dict valueForKey:#"hausNummer"]];
[pers setPlz:[dict valueForKey:#"plz"]];
[pers setStadt:[dict valueForKey:#"stadt"]];
[pers setHandyNummer:(NSInteger*)[dict valueForKey:#"handyNummer"]];
[pers setEmail:[dict valueForKey:#"email"]];
[pers setSteuerSatz:[[dict valueForKey:#"steuerSatz"] floatValue]];
[dict release];
[personenDatenController setPerson:pers];
[navigationController pushViewController:personenDatenController animated:YES];
[personenDatenController release];
[pers release];
The variable "path" comes from the following static method:
+ (NSString *)pathForDocumentWithName:(NSString *)documentName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *tempPath = [documentsDirectory stringByAppendingPathComponent:documentName];
return tempPath;
}
Thanks in advance for your help!
Kind regards
Phil
Assuming that setPerson calls retain on pers. Does your PersonViewController dealloc, call release on that person object? If so, put a breakpoint there (or NSLog) and find out the retainCount of the person. If it's not going to 0, where else might you have retained it?
Thank you guys for your responses.
PersonViewController does retain the person object but I put a release for the person object in dealloc. The retaincount is okay.
I moved the initialization of the Person object to the PersonViewController and now everything is fine. This seems quite strange to me.
Thank you
Regards

NSMutableArray Leaks in Loop

I´m using instruments to find memory leaks, and it found a lots!
But i don´t know how to fix it.
#property(nonatomic, retain) NSMutableArray *wycategories;
...
...
self.wycategories = [[NSMutableArray alloc]init];
...
...
for (CXMLElement *node in nodes) {
//Instruments say that here there are a lots of memory leaks
WaiYahCategory *wycategory = [[WaiYahCategory alloc] init];
wycategory.text = [[node childAtIndex:0] stringValue];
wycategory.idCategory = [[node attributeForName:#"id"] stringValue];
wycategory.desc = [[node attributeForName:#"desc"] stringValue];
wycategory.icon = [[node attributeForName:#"icon"] stringValue];
[self.wycategories addObject:wycategory];
[wycategory release];
}
As the wycategories has a retain attribute, you have to release the array after the assignement.
NSMutableArray *array = [[NSMutableArray alloc]init];
self.wycategories = array; // <- The property retains the array
[array release];

Problem removing multiple objects from NSMutableArray iPhone SDK

I am having trouble removing objects from nsmutable array. Here it is.
NSURL *url = [NSURL URLWithString:#"http://www.lockerz.com/dailies"]];
NSData *datadata = [NSData dataWithContentsOfURL:url];
NSString *removeForArray = [[NSString alloc] initWithData:datadata encoding:NSASCIIStringEncoding];
NSArray *theArray = [removeForArray componentsSeparatedByString:#" "];
NSMutableArray *deArray = [[NSMutableArray array] initWithArray:theArray];
[deArray removeObjectsInRange:NSMakeRange(0, 40)];
NSLog(#"%#", deArray);
+[NSMutableArray array] already returns an initialized array. Don't use an initializer method on that, they are used on new instances that you allocd.
In this case you can either
alloc/init an instance
use -mutableCopy
use a suitable convenience constructor
The three following lines are equivalent:
NSMutableArray *a = [[theArray mutableCopy] autorelease];
NSMutableArray *b = [NSMutableArray arrayWithArray:theArray];
NSMutableArray *c = [[[NSMutableArray alloc] initWithArray:theArray] autorelease];