views:

55

answers:

2

Hello, im fairly new to objective-c, most of it is clear however when it comes to memory managment I fall a little short. Currently what my application does is during a NSURLConnection when the method -(void)connectionDidFinishLoading:(NSURLConnection *)connection is called upon I enter a method to parse some data, put it into an array, and return that array. However I'm not sure if this is the best way to do so since I don't release the array from memory within the custom method (method1, see the attached code)

Below is a small script to better show what im doing

.h file

#import <UIKit/UIKit.h>

@interface memoryRetainTestViewController : UIViewController {

    NSArray *mainArray;

}

@property (nonatomic, retain) NSArray *mainArray;

@end

.m file

#import "memoryRetainTestViewController.h"

@implementation memoryRetainTestViewController
@synthesize mainArray;


// this would be the parsing method
-(NSArray*)method1
{
    // ???: by not release this, is that bad. Or does it get released with mainArray
    NSArray *newArray = [[NSArray alloc] init];
    newArray = [NSArray arrayWithObjects:@"apple",@"orange", @"grapes", "peach", nil];

    return newArray;
}


// this method is actually
// -(void)connectionDidFinishLoading:(NSURLConnection *)connection
-(void)method2
{
    mainArray = [self method1];
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    mainArray = nil;
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)dealloc {
    [mainArray release];
    [super dealloc];
}


@end
+2  A: 

Yes, your newArray is released when mainArray is released. But this just if method2 is called once.

We're talking about references so if you have

newArray = something
mainArray = newArray
[mainArray release]

both variables will be referencing to just a NSArray*. Then in your case newArray is just a local so there's no problem.

The problem occurs if you call method2 twice:

newArray = something
mainArray = newArray
newArray = something2
mainArray = newArray <- old reference is lost
[mainArray release] <- just something2 is released

To avoid this issue you should make sure to release mainArray before overwriting the reference with another object.

EDIT: didn't noticed that you were creating the array twice :) No, that's not good..

Jack
Ya... some of this is coming back to addressing and pointers back in my c++ class last term heh. Thanks for the advice and help.
cdnicoll
+2  A: 

Your -method1 first creates a new array and then overwrites it with a new one:

NSArray *newArray = [[NSArray alloc] init]; // first array, retained
newArray = [NSArray arrayWithObjects:...];  // second array, auto-released, 
                                            // pointer to first one lost

The first array is simply leaked here. You are also leaking the array stored in the ivar, just use the synthesized setter to avoid that - it retains and releases for you.

If you haven't done so yet, read the Memory Management Guide for Cocoa.

A better version:

- (NSArray *)method1 {
    NSArray *newArray = [NSArray arrayWithObjects:...];    
    return newArray;
}

- (void)method2 {
    self.mainArray = [self method1];
}
Georg Fritzsche
Thank you, explained this well.
cdnicoll