Can I force an Autorelase object by calling a release without autorelease pool like that:
NSString *myString = [[[NSString alloc] init] autorelease];
[myString release];
Normally it's like that:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *myString = [[[NSString alloc] init] autorelease];
[pool release];
The first sample will crash, since the string will get over-released. If you want to have control over the lifetime of your autoreleased objects, the correct approach is what your second sample does – create a local autorelease pool that you can drain when you want.
Your code will crash because global auto release pool will try to release the object later. Results in malloc double free error
You can do this:
NSString *myString = [[[NSString alloc] init] autorelease];
Or this:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *myString = [[[NSString alloc] init] autorelease];
[pool release];
But not this:
NSString *myString = [[[NSString alloc] init] autorelease];
[myString release];
Related
Can anybody explain me why does the case1 and case2 crashes while the others does not in case of non-ARC?
Case1:
NSString *rr = [[NSString alloc] initWithString:#"AB"];
[rr release];
[rr autorelease];
Case2:
NSString *rrr = [[NSString alloc] initWithString:#"AB"];
[rrr autorelease];
[rrr release];
Case3:
NSMutableString *rr1 = [[NSMutableString alloc] initWithString:#"AB"];
[rr1 release];
[rr1 autorelease];
Case4:
NSMutableString *rrr1 = [[NSMutableString alloc] initWithString:#"AB"];
[rrr1 autorelease];
[rrr1 release];
Case5:
NSArray *rr3 = [[NSArray alloc] initWithObjects:#"jj", nil];
[rr3 release];
[rr3 autorelease];
Case6:
NSArray *rrr3 = [[NSArray alloc] initWithObjects:#"jj", nil];
[rrr3 autorelease];
[rrr3 release];
Case7:
NSMutableArray *rr2 = [[NSMutableArray alloc] initWithObjects:#"jj", nil];
[rr2 release];
[rr2 autorelease];
Case8:
NSMutableArray *rr2 = [[NSMutableArray alloc] initWithObjects:#"jj", nil];
[rr2 autorelease];
[rr2 release];
All are are incorrect because eventually all will be released twice, but some may coincidentally not crash.
The alloc allocates the object with a retain count of 1. release decreases the retain count 1. autorelease eventually decreases the retain count 1. That means that all are over released.
But as #Chuck mentions some instances are constants, are created at compile time and never released so release and autorelease can be called to many tines with no crash.
String constants are one instance of this this where over-releasing will not cause a crash:
NSString *s = #"aa";
Even over-releasing this is OK because the compiler is smart enough:
NSString *s = [NSString stringWithString:#"aa"];
But you will get a warning from the current LLVM compiler that using stringWithString with a literal is redundant.
In my Code showing 2 places memory leakage please see and Help me.
1.FIRST
UIButton *push = (UIButton *)sender;
NSString *string = [NSString stringWithFormat:#"%#",[push currentTitle]];
NSArray *chunks = [[NSArray alloc]initWithArray:[stringcomponentsSeparatedByString:#"-"]];
list = [[NSMutableArray alloc]initWithArray:chunks];
(NSMutableArray *list;)
[chunks release];
2.SECOND
Here is The Source Code First
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSURL *url = [[NSURL alloc]initWithString:#"http://www/absdf.com/myXML.xml"];
self.parser = [[NSXMLParser alloc]initWithContentsOfURL:url];
[parser setDelegate:self];
[parser parse];
[parser release];
[url release];
[pool drain];
while i am excuting this code and with this Instruments Tools on line number : 2 show memory leakage with heaviest backtraces.
So please let know the Reason .?
In addition to the other answers your pool should be released
NSAutoreleasePool *pool = [NSAutoreleasePool new];
//... then
[pool release];
Obviously, list = [[NSMutableArray alloc]initWithArray:chunks]; is never released.
self.parser = [[NSXMLParser alloc]initWithContentsOfURL:url];
alloc/init returns a retained object, and if you your parser property is declared with retain attribute, then you are over retaining it. It should be:
self.parser = [[[NSXMLParser alloc]initWithContentsOfURL:url] autorelease];
P.S. Make sure you are doing proper memory management to your list instance variable. Just to be sure you better use properties.
list should be release somewhere, maybe in dealloc
- (void)dealloc {
[list release];
[super dealloc];
}
parser = [[NSXMLParser alloc]initWithContentsOfURL:url];
or
NSXMLParser *tempParser = [[NSXMLParser alloc]initWithContentsOfURL:url];
self.parser = tempParser;
[tempParser release];
I noticed a piece of code somewhere it does
NSMutableString *myString = [[NSMutableString string] autorelease];
Is it overkill? Shouldn't it be the same as [NSMutableString string]?
NSMutableString *myString = [[NSMutableString string] autorelease];
will lead to a crash if they aren't calling retain on it elsewhere.
[NSMutableString string]
is the same as
[[[NSMutableString alloc] init] autorelease]
Doesn't look right to me. Are you sure that the example you saw is actually doing this?
[NSMutableString string] is equivalent to
[[[NSMutableString alloc] init] autorelease]
So with the example you provided, you would get
[[[[NSMutableString alloc] init] autorelease] autorelease]
which would result in an over release and an exc_bad_access error.
NSString* strSubject = [[NSString alloc] initWithData: temp encoding:
NSISO2022JPStringEncoding];
i got a memory message "Potential leak of an object allocated" on above line.
Is there any alternate way to write same.
You will get that sort of message unless you either release it or put it in the autorelease pool.
This can be done by:
NSString* str = [[NSString alloc] initWithData: blah blah blah ... ];
[str release];
to do it immediately. You can also use:
NSString* str = [[NSString alloc] initWithData: blah blah blah ... ];
[str autorelease];
to have it released at some point in the future.
You need to do [strSubject release] later, or [strSubject autorelease] either later or immediately. I'd use this:
NSString* strSubject = [[[NSString alloc] initWithData:temp encoding:NSISO2022JPStringEncoding] autorelease];
Sadly there isn't a NSString factory method stringWithData:, but that's equivalent.
In fact any [NSString stringWithBlah:xx] method is more or less equivalent to [[[NSString alloc] initWithBlah:xx] autorelease]
-(void) getAccounts {
self.selAccounts = [[NSMutableArray alloc] init];
self.accounts = [[NSMutableArray alloc] init];
NSString *url=[NSString stringWithFormat:#"https://localhost//listaccts"];
self.processor=[[AsynConnectionProcessorController alloc] init];
self.processor.delegate=self;
self.processor.server=self.server;
[processor createRequestfromURL:url];
}
This method is causing memory leak when invoked. Now if I replace this with below
-(void) getAccounts {
[accounts release];
self.selAccounts = [[NSMutableArray alloc] init];
accounts = [[NSMutableArray alloc] init];
NSString *url=[NSString stringWithFormat:#"https://localhost//listaccts"];
self.processor=[[AsynConnectionProcessorController alloc] init];
self.processor.delegate=self;
self.processor.server=self.server;
[processor createRequestfromURL:url];
}
I am getting memory leak if I invoke this method second time as a result of viewcontroller beong popped from stack.
Why does this leak? accounts is an insyance variable with declration like this :
#property (nonatomic, retain) NSMutableArray *accounts;
Can't I assume that there won't be memory leak if I use setter via self.accounts?
This is wrong
self.accounts = [[NSMutableArray alloc] init];
the setter already does a retain, since you specified that in the property
#property (nonatomic, retain) NSMutableArray *accounts;
you should rewrite it like this
NSMutableArray arr = [[NSMutableArray alloc] init];
self.accounts = arr;
[arr release];
or alternatively:
self.accounts = [[[NSMutableArray alloc] init] autorelease];
EDIT: removed 'non preferred' - was subjective.