views:

195

answers:

3

Hi

I am quite new to Objective C for the iPhone, so I hope you wont kill me for asking a simple question.

I have made an App that works fine, except that Instruments reports memory leaks from the class below. I use it to store settings from one class and then retrieve them from another class. These settings are stored on a file so they can be retrieved every time the App is ran.

What can I do do release the "setting" and is there anything that can be done to call (use) the class in a smarter way?

Thanks

----- Below is Settings.m -----

#import "Settings.h"

@implementation Settings

@synthesize settings;

-(NSString *)dataFilePath  // Return path for settingfile, including filename
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];

    return [documentsDirectory stringByAppendingPathComponent:kUserSettingsFileName];
}

-(NSMutableArray *)getParameters  // Return settings from disk after checking if file exist (if not create with default values)
{
    NSString *filePath = [self dataFilePath];

    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) // Getting data from file
    {
        settings = [[NSMutableArray alloc] initWithContentsOfFile:filePath];
    }

    else // Creating default settings

    {   
        settings = [[NSMutableArray alloc] initWithObjects:
                        [NSNumber numberWithInteger:50],        
                        [NSNumber numberWithInteger:50],        
                        nil];

        [settings writeToFile:[self dataFilePath] atomically:YES];

    }
    return settings;
}


    ----- Below is my other class from where I call my Settings class -----

    // Get settings from file
    Settings *aSetting = [[Settings alloc] init];

    mySettings = [aSetting getParameters];
    [aSetting release];
+1  A: 

In your -getParameters method you alloc/init an NSMutableArray ([[NSMutableArray alloc] initWithContentsOfFile:filePath] - i.e. retain count of 1) which you never release. You should autorelease your array before returning it: return [settings autorelease].

Note that if you need to put the setting parameters in your mySettings variable and want to keep it around, you should do mySettings = [[aSetting getParameters] retain]; so that the retain count does not drop to 0.

Yang
Hi again. Tried with the autorelease, but it doesnt work. Still same results.Thanks for the try though.
Structurer
Some more details. When running with the autorelease in the code, the app will not start on the phone with Instruments running. Without instruments it works fine, but so it does w/o the autorelease ;-)
Structurer
+1  A: 

Or, better yet:

  1. declare the settings property as a retaining property, then
  2. use self.settings instead of settings in your -getParameters method, and finally
  3. call autorelease on your arrays right after alloc/initting them.
Yang
Thanks YangJust a question, should I not avoid aurorelease when coding for the iPhone?
Structurer
I'd say it depends on your app. In the end you trade performance for readability. See http://stackoverflow.com/questions/193288/what-is-the-cost-of-using-autorelease-in-cocoa and http://stackoverflow.com/questions/613583/why-is-autorelease-especially-dangerous-expensive-for-iphone-applications for a discussion of the pros and cons.In my suggestion, instead of "(3) call autorelease" you could do the following:NSArray *tempArray = [[NSMutableArray alloc] init...];self.settings = tempArray;[tempArray release];
Yang
A: 

Hi

Managed to solve the Settings class by modifying two lines:

1: Using settings = [NSMutableArray arrayWithContentsOfFile:filePath] instead of settings = [[NSMutableArray alloc] initWithContentsOfFile:filePath]

2: In a similar way using settings = [NSMutableArray arrayWithObjects: instead of settings = [[NSMutableArray alloc] initWithObjects

Now I only have to solve the leak I have when I create these from another class. Any ideas how?

Structurer