I have a problem with my code that for the life of me I can’t figure out, not even with all previous threads here on SO.
I’m pulling data from a JSON source and putting it in an NSDictionary as stated in tutorials and on SO. When profiling the app, I notice a memory leak caused by this NSDictionary but releasing it at the end of this function crashes the app. Any suggestions?
(By the way: I’m new to Obj-C and programming in general, so this code is mostly cherrypicked from various sources.)
- (void)fetchedData:(NSData *)responseData {
//parse JSON for empty return
if([responseData length] != 0){
NSError* error = nil;
//Convert JSON data to Obj-C
NSDictionary* allShotData = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSString *player = [[allShotData objectForKey:@"player"] objectForKey:@"name"];
NSString *shotDribbblePage = [allShotData objectForKey:@"url"];
NSString *shotTitle = [allShotData objectForKey:@"title"];
NSURL *imageURL = [NSURL URLWithString:[allShotData objectForKey:@"image_url"]];
shotPageURL = [shotDribbblePage retain];
//***********************
// Setup a-sync loading of shot
//***********************
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadImage:) object:imageURL];
[queue addOperation:operation];
[operation release];
[queue release];
}
else{
airballCount++;
if (airballCount <= 20) {
[self getDribbbleData];
}
else{
NSLog(@"Too many airballs. Bailing out");
[self showNoConnectionModal];
}
}
}
Here:
you should probably use the accessor:
I should really emphasize that you should use your accessors everywhere since they do your ref counting for you (exception: not in initializers and dealloc). As beryllium also notes, you could do your ref counting manually if there is no accessor. That takes the basic form:
If it’s the contents of the returned dictionary that are leaking, then it’s how you have used/referenced the contents when read (over-retain).
If you’re using your class in a concurrent context, then you will usually need a lock.
If you’re loading a
UIImageor otherwise interacting with UIKit objects from a secondary thread — that’s not good.