2

I know that the basic rule of memory management in objective-C is that for every object you do an alloc, you need to release it somewhere.

Say I have the following:

@interface NewPollViewController : UIViewController 
{
   NSMutableArray * myArray;
}

@property (nonatomic, retain) NSMutableArray * myArray;

@implementation NewPollViewController
@synthesize myArray = _myArray;

- (void) viewDidLoad
{
  [super viewDidLoad];
  self.myArray = [[NSMutableArray alloc] init];
}

Say that this self.myArray is used as a dataSource of a UITableView, so when and where should I release this? In the dealloc? I guess that the release in the dealloc corresponds to the retain that I've set in my property, so where do I release

xonegirlz
  • 8,889
  • 19
  • 69
  • 127

3 Answers3

3

In your example you technically need to release it twice - once in dealloc, and once immediately after setting the property:

NSMutableArray *a = [[NSMutableArray alloc] init];
self.myArray = a;
[a release];

The reasoning for this is because you are specifically allocating memory in viewDidLoad, and then also increasing the retain count when setting the property.

A way to avoid this is to use one of the static NSMutableArray constructors or use autorelease i.e.

self.myArray = [[[NSMutableArray alloc] init] autorelease];

Alternatively, bypass the property altogether:

myArray = [[NSMutableArray alloc] init];

This would avoid the extra retain generated by the property (in fact you could get rid of the property statement if it was only used locally).

Paul Mason
  • 1,129
  • 8
  • 15
1

If I want to expose a NSMutableArray I would do this:

@interface NewPollViewController : UIViewController 
{
   NSMutableArray * myArray;
}

@property (nonatomic, readonly) NSMutableArray * myArray;

@implementation NewPollViewController
@synthesize myArray;

- (void) viewDidLoad
{
  [super viewDidLoad];
  self.myArray = [[NSMutableArray alloc] init];
}

- (void) dealloc
{
   [myArray release],myArray = nil;
}

Changed the property to readonly because its mutable array you don't want other classes to change this array and you are properly alloc and releasing it.

ARC
  • 1,794
  • 2
  • 17
  • 21
  • The NSMutableArray was only an example, it can be any objects – xonegirlz Sep 26 '11 at 02:17
  • If its String Literal and an iVar assigned to it, then you don't alloc and release it. If its String object you would use copy and don't need to alloc and init in viewDidLoad. usually you don't call alloc on property with retain. – ARC Sep 26 '11 at 02:21
  • 1
    @Nikita - your code will technically leak. To set the property in one line you should be using one of the NSMutableArray static constructors or autorelease. Unless of course you remove "self" from where you initialise the array. See http://stackoverflow.com/questions/156243/object-allocate-and-init-in-objective-c/167783#167783 – Paul Mason Sep 26 '11 at 02:44
  • Why would my code leak ? its readonly not retained property. Since there is an iVar in interface self.myArray has same effect as using myArray. If I am just using properties without iVar then I have to use self. – ARC Sep 26 '11 at 05:57
0

In your case I would often release it in the viewDidUnload, and also in dealloc.

I like to maintain a mirror with respect to where the memory is allocated. When its done in viewWillAppear, I release in viewWillDisappear.

Now since you are saying this is used thru-out the class, I would allocate in an init method, or the awakeFromNib, and then just release it once in dealloc.

EricLeaf
  • 892
  • 5
  • 12
  • For your third option, you still will have to release it twice... Why is it that when you Lloc in init you only have to release it once? – xonegirlz Sep 26 '11 at 02:19
  • Because its not related to the view or wether its loaded or visible. When it finally goes to `dealloc` is when you want to release it. If this were `myArrayOfSubviews` then you would probably do the load/unload creation and release to respond properly to memory warnings. – EricLeaf Sep 26 '11 at 14:58