Yesterday I assked a question about memory management and Singletons ( Proper Management Of A Singleton Data Store In IOS With Web Service ). I have been racking my brain for the past 36 hours trying to track down the issue and after extensive testing with NSLog, etc, I can only conclude that objects allocated within blocks are not being autoreleased. I've used blocks as a way to handle the asynchronous webservice responses. I also send a block from the view controller that needs to make the web service request so that it can perform any actions based on the web service's response. In the hopes that a comprehensive overview of my code will help obtain a solution, I'm putting all the code that is generating the issue here:
The first step is making a request from my root view controller. When it loads, I request all the user's "Hollers" a term that I'm using internally to essentially mean events. When the root view controller loads, I call a method which contains the following code:
HollerWebService *api = [[HollerWebService alloc]init];
//NSLog(@"About to get the hol开发者_运维知识库lers for userId: %@", [[[CurrentSession defaultStore]currentUser]userId]);
[api getLatestHollers:[[[CurrentSession defaultStore]currentUser]userId] completionBlock:^(BOOL succeeded) {
//If the user has 0 hollers, display one of the illustrations
[self.tableView reloadData];
[self stopLoading];
if( !succeeded ){
UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Could not connect to Holler" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[av show];
[av release];
}
else
{
for( Holler *hN in [[HollerStore defaultStore] allHollers] )
{
//Retain count of all the hollers is
NSLog(@"Retain count of the holler is %i", [hN retainCount]);
}
}
}];
[api release];
As you can see, I have a commented area which prints out the retain count to NSLog that was part of my debugging process. At this point, it's telling me the retain count of each object is 2, meaning that the original Holler generated in the next set of code has not yet been autoreleased. The next set of code is within my actual web service. I have included comments around the key part of this method which is resulting in increased retain counts:
- (void)getLatestHollers: (NSString *)userId completionBlock:(void (^)(BOOL succeeded))handler
{
[self getRequest:[[NSString alloc]initWithFormat:@"hollers/feed?user_id=%@",userId] completionBlock:^(NSData *receivedData, NSURLResponse *receivedResponse, NSError *error) {
if( error == nil )
{
SBJsonParser *json = [SBJsonParser new];
NSArray *response = [json objectWithData:receivedData];
[json release];
//NSLog(@"Got the latest Hollers. %@", response);
HollerStore *hStore = [HollerStore defaultStore];
for( NSDictionary *holler in response )
{
//At this point Holler *h is being sent an autoreleased holler
//from the parseHoller: method. At this point it's retain count is 1
Holler *h = [self parseHoller:holler];
[hStore addHoller:h];
//Now that I've added it to my singleton the retain count is 2, although I'm
//assuming the autorelease pool will eventually come through and reduce this
//to 1 but it never happens
}
handler(YES);
}
else
{
NSLog(@"The API failed :(, %@", [error localizedDescription]);
//Let the requestor know that this request failed
handler(NO);
}
}];
}
At this point the retain count remains at 2, not 1, so when I go to remove the object from my singleton, it results in a memory leak. The only thing that I can conclude is that I'm having some sort of block-related memory issues. If anybody could provide some insight it would be much appreciated!!!
You should never be using retainCount
at all, ever - really Apple should just remove it from the SDK as it's not useful at all. Check out this question for the technical reasons as to why you shouldn't be using it point blank:
When to use -retainCount?
I am going to hop over to the original question where somebody posted that you should use it and point this out. You may well have a memory leak, but retain count isn't the right thing to use to solve it!
精彩评论