iphone how to release memory in this case - iphone

I have a method like this
- (NSDictionary *)getCellValuesForRow:(int)row {
NSMutableDictionary *dictValues= [[NSMutableDictionary alloc] init];
Outage *outage = [listOutage objectAtIndex:row];
[dictValues setObject:outage.duration forKey:#"OutageDuration"];
return dictValues;
}
and this value is stored in this way
NSDictionary *dict = [[NSDictionary alloc] initWithDictionary:[self getCellValuesForRow:(indexPath.row-1)]];
how to release memory in this scenario

This is what autorelease is for.
NSMutableDictionary *dictValues= [[[NSMutableDictionary alloc] init] autorelease];

You should autorelease dictValues in getCellValuesForRow, or just don't alloc it. This will keep it autoreleased:
NSMutableDictionary *dictValues= [NSMutableDictionary dictionary];
In most cases it should be the responsibility of whatever calls it to alloc it (if it needs to be kept around after the autorelease pool is cleared), then dealloc it later.
If whatever calls it doesn't need it kept around, it can just leave it autoreleased.

An alternative is to simply use
NSMutableDictionary *dictValues= [NSMutableDictionary dictionary];
That's effectively the same thing as what Dan suggested. Just less typing.
It applies to your next line, too:
NSDictionary *dict = [NSDictionary dictionaryWithDictionary:[self getCellValuesForRow:(indexPath.row-1)];

Related

Releasing Object is it necessary?

I am stuck in the middle of memory management stuff. Please help me out in solving my question.
NSMutableArray *array = [[NSMutableArray alloc]init];
Object *obj = [[Object alloc]init];
[array addObject: obj];
[obj release];
Is it necessary to release obj in above code?
The answer to your question is: yes, if you don't use ARC. If you are writing a new app, you should seriously consider using ARC.
Container objects in Objective-C always balance their retain/release count. In other words, you should always manage memory as if you did not add the object and make sure your own code balances its retain count. Note that this is a convention and is not enforced, but you could always trust the built-in classes to follow this convention. Also, you can perform a static analysis (Cmd+Shift+B in XCode) to detect these problems. It would have pinpointed this in your code above.
The correct code in the case above would be:
NSMutableArray *array = [[NSMutableArray alloc]init];
Object *obj = [[[Object alloc]init]autorelease];
[array addObject: obj];
or
NSMutableArray *array = [[NSMutableArray alloc]init];
Object *obj = [[Object alloc]init];
[array addObject: obj];
[obj release];
since NSMutableArray (and its cousins) will retain the object as long as it is in the collection.

objective-c memory leak + NSMutableDictionary

I am using a dictionary with parameters to send to a web service. I keep getting memory leaks from it, altho I do a release for the object. My code:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// getting an NSString
NSString *clientID = [prefs stringForKey:#"ClientID"];
//Call web service
id delegate1 = self;
AsyncWebServiceController * webService = [[[AsyncWebServiceController alloc] initWithDelegate:delegate1
selSucceeded:#selector(webServiceConnectionSucceeded:)
selFailed:#selector(webServiceconnectionFailed:)] autorelease];
NSMutableDictionary *params = [[NSMutableDictionary alloc] init]; //Memory leak here
[params setValue:clientID forKey:#"clientId"]; //Memory leak here
[params setValue:[self.jobDetails objectForKey:#"BoardId"] forKey:#"jobBoardId"];
[params setValue:[self.jobDetails objectForKey:#"Id"] forKey:#"jobId"];
[webService startRequest:#"JobReviewGet" parameters:params];
[params release];
Any ideas? Thanks!!
Build with analyze. That may give some pointers.
Outside of that:
You are calling alloc on AsyncWebServiceController do you own it but the code above does not release.
You should be calling setObject:forKey instead of setValue:ForKey. setValue is for KVC.
You should be using :
- (void)setObject:(id)anObject forKey:(id)aKey;
Thus you code should look like:"
NSMutableDictionary *params =
[[NSMutableDictionary alloc] init]; //Memory leak here
[params setObject:clientID forKey:#"clientId"]; //Memory leak here
[params setObject:[self.jobDetails objectForKey:#"BoardId"] forKey:#"jobBoardId"];
[params setObject:[self.jobDetails objectForKey:#"Id"] forKey:#"jobId"];
[webService startRequest:#"JobReviewGet" parameters:params];
[params release];
What does [webService startRequest:#"JobReviewGet" parameters:params]; method do with the param, does it retain it? If so you also need to release it there.
Also ar some point you will need to release the webService.
Why don't you use the convenience constructor?
NSMutableDictionary *params = [NSMutableDictionary dictionary];
Then there would be no need to release it. This should solve your problem.
Are you releasing your webService object at some point? Also is the delegate of AsyncWebServiceController an assigned or retained property? Delegates should generally be assigned properties to avoid retain loops.

NSDictionary Memory leaks

I implement a method to return a dictionary in my app. But I find a memory leak using instrument, I tried to figure it out, but I still cannot find it. Can anyone help me out?
Thanks in advance, here is the code for that methods:
-(NSMutableDictionary *)initDict
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
[dict setObject:self.name forKey:#"Name"];
//Some similar set object for key here...
return dict;
}
I think the problem is from allocing memory for dict and not releasing it. But in the method, it seems I cannot release dict. So is there any method to fix the leak?
All variants are good. Here is third variant (choose wisely):
Replace
NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
with
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
I think you just need to change the last line of initDict to this:
return [dict autorelease];
When you are creating any object in your function and you want to return them then you should always create it in a way that those objects are autoreleased. So you should change your code like below.
NSMutableDictionary *dict = [[[NSMutableDictionary alloc]init]autorelease];
So whenever you create any object just call autorelease method on that.

Memory management with NSDictionary

I found an answer to this a while ago, and made a mental note to fix it, but now I can't for the life of me find the post again.
Very simple - my current method for adding dictionaries to an array is leaky. Please, what is the best way to ensure they are being released properly? My method:
[beachPresenters addObject:[[NSMutableDictionary alloc]initWithObjectsAndKeys:
#"Kayak rides",#"name",#"kayak_sm.png",#"smPhoto",#"kayak_med",#"medPhoto",#"Free kayak rides for kids",#"description",#"",#"Friday",
#"All day! 10.00am - 6.00pm",#"Saturday",#"",#"Sun",#"Beach",#"stage",#"Blah blah blah",#"blurb",nil]];
beachPresenters (I assume it's an array) takes ownership of the dictionary, so the +1 to the reference count caused by +alloc/-init of the dictionary is not balanced. Thus, the dictionary is leaked.
Use the convenience method equivalent to balance the retain:
NSDictionary *presenter = [NSDictionary dictionaryWithObjectsAndKeys: ...];
[beachPresenters addObject: presenter];
Your array beachPresenters retains the mutable array you created, but your array as created in your example already has a retain count of one. So even if you dispose of beachPresenters, your dictionary will still be retained, i.e., leaked.
Use [NSMutableDictionary dictionaryWithObjectsAndKeys:] instead.
You can have implementation like below:
NSMutableDictionary *dict = [[NSMutableDictionary alloc]initWithObjectsAndKeys:
#"Kayak rides",#"name",#"kayak_sm.png",#"smPhoto",#"kayak_med",#"medPhoto",#"Free kayak rides for kids",#"description",#"",#"Friday",
#"All day! 10.00am - 6.00pm",#"Saturday",#"",#"Sun",#"Beach",#"stage",#"Blah blah blah",#"blurb",nil];
[beachPresenters addObject:dict];
[dict release];
or
NSMutableDictionary *dict = [[[NSMutableDictionary alloc]initWithObjectsAndKeys:
#"Kayak rides",#"name",#"kayak_sm.png",#"smPhoto",#"kayak_med",#"medPhoto",#"Free kayak rides for kids",#"description",#"",#"Friday",
#"All day! 10.00am - 6.00pm",#"Saturday",#"",#"Sun",#"Beach",#"stage",#"Blah blah blah",#"blurb",nil] autorelease];

Question about memory usage

I have the following method:
+(NSMutableDictionary *)getTime:(float)lat :(float)lon {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setObject:hour forKey:#"hour"];
[dictionary setObject:minute forKey:#"minute"];
[dictionary setObject:ampm forKey:#"ampm"];
return dictionary;
}
A lot of the method is chopped off, so I think I need the pool for some other stuff in the method. Here's my question. I know that I need to release the following objects:
[dictionary release];
[pool release];
However, I can't release the dictionary before I return it, but as soon as I return it the rest of the method isn't performed. What should I do?
You could always autorelease the dictionary, thereby ensuring it is kept in memory at least until getTime:: returns. This conforms well to the memory paradigm on Cocoa, where a method which returns an object which it creates (but does not own), calls autorelease on it when it no longer needs it.
Of course, make sure to retain that dictionary in any code that receives it from getTime::.