I have a problem with objects allocation and release.
I’m working on some app with image editing feature.
When user taps to pick an image, then UIImagePickerController is presented, then when user picks the image from the library, UIImagePickerController dismisses and then there is a method:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
//some logic
FilterViewController *filterViewController = [[FilterViewController alloc] initWithImage:imageToWorkWith
withDelegate:self];
/* present image processing screen, then release it */
[((UIViewController *)self.delegate) presentModalViewController:filterViewController animated:NO];
[filterViewController release];
}
Then appears FilterViewController – the image editing screen. After tapping the “Done” button, the next method will be called:
- (void)dismissWithDone {
[self.filterViewDelegate doneImageEdittingWithImage:self.imageToWorkWithView.image];
}
which invokes:
#pragma mark - FilterViewDelegate
- (void)doneImageEdittingWithImage:(UIImage *)imageToSend {
//some logic
[((UIViewController *)self.delegate) dismissModalViewControllerAnimated:NO];
}
All seems to work properly, but the problem is, that filterViewController is not deallocating and persist in memory. And if I will choose to edit some photo one more time, I mean if method with creation of filterViewController will be invoked one more time, then the previous instance will be deallocated and the new one will be presented, and so on.
I think that when [UIViewController setChildModalViewController:] is invoked, the previous instance of filterViewController is deallocated then, when it sets the new instance.
In case of adding one more release:
[((UIViewController *)self.delegate) presentModalViewController:filterViewController animated:NO];
[filterViewController release];
[filterViewController release];
then it will be deallocated after dismissing, but on creating of new instance will be bad_access, cause it will try to dealloc the deallocated instance.
What I do not understand:
1. Why after dismissing of filterViewController, there is still reference count greater than 0 on it, that causes not to dealloc it?
2. Why, in case of adding one more release, the reference of deallocated object still persists in childModalViewController?
The cause for all the troubles that I had here was, that I was not setting to nil certain property of block in certain class that I used in that UIViewController. For instance: I use GPUImage framework in this UIViewController, and I’m setting block:
So, I was not setting nil to clean this block property before dismissing the UIViewController:
and that was the reason, that dealloc was not invoked on UIViewController.
In addition here is explanation about blocks and why we need to set theirs properties to nil.