0

i got encountered with a strange issue relating to memory management in iphone.

i explain it through a example consider a below written piece of code

in XMLParser.h

@interface XMLParser:NSObject/*<NSXMLParserDelegate>*/ {
    NSMutableArray *parsedXML;

}
@property (nonatomic, retain) NSMutableArray *parsedXML;

in XMLParser.m if i write my init function like below written form #import "XMLParser.h"

@implementation XMLParser

@synthesize parsedXML;

- (XMLParser *) initXMLParser :(NSString *)repetingTagStr{

self = [super init];
   if(self){
       self.parsedXML = [[NSMutableArray alloc] initWithCapacity:1];
       NSLog(@"%d", [self.parsedXML retainCount]); 
   [self.parsedXML release];

    }

return self;
}

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

@end

NSLog gives retain count as 2 and when after release statement if i try to use it then it gives a crash.

now if i alloc it using NSMutableArray* temp = [[[NSMutableArray alloc]initWithCapacity:1]autorelease]; or self.parsedXML = [NSMutableArray arrayWithCapacity:1]; then it works fine.

i am really very confused now as how autorelease does not give crash and immediate release cause it to crash. is it something to do with accessor methods. Please explain where my concepts are failing in memory management :)

vikas
  • 488
  • 8
  • 18

3 Answers3

1

Since you have declared your property as (assign), when you set self.parsedXML = ... it will not be automatically retained. Try using a (retain) property instead.

jtbandes
  • 115,675
  • 35
  • 233
  • 266
  • thanks.. sorry, by mistake i put assign there, actually its retain, and result i shared here are with retain property. actually i was testing something and i put same code with assign here, can you please explain now that why this happening with retain property here – vikas Aug 19 '11 at 09:43
  • actually this the only code and this function "initXMLParser" is called with creation af an instance of class XMLParser. you can simply put above init code in a viewdidload of any viewcontroller class and check its results. immediate release is giving crash and autorelease is working fine with accessor methods.... :( – vikas Aug 19 '11 at 10:08
1

Never rely on results from retainCount. see here for more details

Let's debug your example in mind. You create an instance of NSMutableArray and because of definition of your accessor method it is directly assigned to your member variable. Retain count still remains at 1 because at creation time this counter is set to 1 and assigning don't increase it. Then your release your array. Retain count drops to 0 and your array is sent to nirvana. Accessing your array after releasing will crash your app, that is what you already have recognized.

While creating your NSMutableArray with autorelease (both of your shown examples do so) the retain counter of the array still is 1. But release isn't sent immediately. It is sent after the current iteration of event loop. And that is why you can access the array during your method.

My suggestion: use your first approach and remove your release after array creation. Within dealloc-method you do already release your array so no memory leak would occur, everything is fine.

Community
  • 1
  • 1
TRD
  • 1,027
  • 11
  • 20
  • thanks TRD... sorry, by mistake i put assign there, actually its retain, and result i shared here are with retain property. actually i was testing something and i put same code with assign here, can you please explain now that why this happening with retain property here – vikas Aug 19 '11 at 09:42
1

Firstly, ignore retainCount - I cannot stress that enough!

The code you've posted (with the property set to retain) won't crash. It must be something else that's causing your error :)

Add the line of code that crashes to your question and we can help more.

deanWombourne
  • 38,189
  • 13
  • 98
  • 110