Is dealloc method called in presentModalViewController when dismiss the controller - iphone

here the following code is used to view the present modal view controller.
[[self navigationController] presentModalViewController:doctorListViewNavigationController animated:YES];
the close action is in the next view controller(DoctorListViewController). You can understand by seeing the following code I added now cleary.
-(void)doctorsListAction
{
if(isFirst == YES)
{
[self getDoctorsListController];
[[self navigationController] presentModalViewController:doctorListViewNavigationController animated:YES];
}
}
-(void)getDoctorsListController
{
DoctorListViewController *doctorListViewController=[[DoctorListViewController alloc]init];
doctorListViewController.doctorList=doctorList;
doctorListViewNavigationController=[[UINavigationController alloc]initWithRootViewController:doctorListViewController];
doctorListViewNavigationController.navigationBar.barStyle= UIBarStyleBlackOpaque;
[doctorListViewController release];
//code in next DoctorListViewContrller to dismiss the view.
//code for dismiss the ModalViewController.
-(void)closeAction
{
[[self navigationController] dismissModalViewControllerAnimated:YES];
}
My problem is the dealloc method is not called then I am getting memory issue problems like object allocations, leaks..
- (void)dealloc
{
[doctorList release];
[myTableView release];
[super dealloc];
}

Dealloc method is called when object is released same number of times, as it was retained.
When you add doctorListView... (let's call it view) to navigationController (let's call it controller), the controller retains the view. And it was also retained during creation. That's why you should release this view twice: one time with dismissModalView... and one with direct release.
I mean something like this:
[[self navigationController] presentModalViewController:doctorListViewNavigationController animated:YES];
[doctorListViewNavigationController release]; // first time
...
- (void)closeAction {
[[self navigationController] dismissModalViewControllerAnimated:YES];
// second time
}

Related

MBProgress view and pushing a view controller doesn't display

MPProgressView won't display when I try to push a viewcontroller until seconds before the pushed VC is displayed. Should the viewController be placed in the same function as the MBProgressView is displayed? I've made sure that my MBProgressView is on the main thread, I've tried many solutions on SO and can't see anyone with the same issue. I am simply trying to display the MBProgressHUD while the viewController is loading and being pushed. Thanks!
I am using MBProgressView as follows:
- (IBAction)pushButton:(id)sender
{
self.HUD =[MBProgressHUD showHUDAddedTo:self.view animated:YES];
[self.view addSubview:self.HUD];
self.HUD.labelText = #"Doing stuff...";
self.HUD.detailsLabelText = #"Just relax";
self.HUD.delegate=self;
[self.view addSubview:self.HUD];
[self.HUD showWhileExecuting:#selector(loadCreate) onTarget:self withObject:nil animated:YES];
}
- (void)loadCreate {
[self performSelectorOnMainThread:#selector(dataLoadMethodMail) withObject:nil waitUntilDone:YES];
}
-(void)dataLoadMethodMail
{NSLog(#"data load method is displaying");
SelectViewController *mvc = [[SelectViewController alloc] init];
[self.navigationController pushViewController:mvc animated:YES];
}
You don't need to add self.HUD to self.view, showHUDAddedTo: does it for you.
[self.HUD showWhileExecuting:#selector(loadCreate) onTarget:self withObject:nil animated:YES];
Shows the hud until loadCreate returns.
[self performSelectorOnMainThread:#selector(dataLoadMethodMail) withObject:nil waitUntilDone:YES];
dispatches something on main thread and returns right after (before the actual end of dataLoadMethodMail). The HUD is shown but disappears right away.
To solve the issue try hiding manually the HUD when dataLoadMethodMail finishes it's work.
Just replace
[self.HUD showWhileExecuting:#selector(loadCreate) onTarget:self withObject:nil animated:YES];
with
[self loadCreate];
and add
dispatch_async(dispatch_get_main_queue(), ^{
[self.HUD hide:YES];
});
at the end of dataLoadMethodMail
PS : Loading data should not be done on main thread.

Presenting View Controller from a block doesn't animate

I am using SVPullToRefresh
__weak InventorySearch *safeSelf = self;
[self.tableView addPullToRefreshWithActionHandler:^{
[safeSelf refresh];
}];
The method refresh does some setup work then calls [self presentmodalviewcontroller:controller animated:YES];
However the view doesn't animate and is simply presented immediatley.
Instead of
[safeSelf refresh];
try this
[safeSelf performSelectorOnMainThread:#selector(refresh) withObject:nil waitUntilDone:NO];

dismissing modalViewController of modalViewController

So I have a UITabBarController app and I want to display a login page, and so I did:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(userDidLogin:) name:UserDidLoginNotification object:nil];
LoginViewController* loginViewController = [[LoginViewController alloc] init];
self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:0];
[self.tabBarController.selectedViewController presentModalViewController:loginViewController animated:NO];
[loginViewController release];
Inside my LoginViewController I can as well show another modalViewController:
- (void) twitterLogin: (UIViewController *) askingView
{
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine: _twitter delegate: self];
if (controller) {
self.askingView = askingView;
[askingView presentModalViewController: controller animated: YES];
}
}
I have the following method where the askingView is the LoginViewController,
when I want to dismiss this I do:
[self.askingView dismissModalViewControllerAnimated:YES];
[[NSNotificationCenter defaultCenter] postNotificationName:UserDidLoginNotification object:nil];
However, this doesn't dismiss the LoginViewController and show the UITabBarController views.. it just dismisses my modalViewController shown from the LoginvVIewController. What am I doing wrong here? I am also getting the following error:
attempt to dismiss modal view controller whose view does not currently appear. self = <LoginViewController: 0x2aff70> modalViewController = <SA_OAuthTwitterController: 0x2d2a80>
2011-09-16 09:45:37.750 VoteBooth[4614:707] attempt to dismiss modal view controller whose view does not currently appear. self = <MainViewController: 0x29fec0> modalViewController = <LoginViewController: 0x2aff70>
In order to dismiss a modal view that is presented over another modal view, you have to call dismissModalViewControllerAnimated: on the parent of the parent. I have used this in some of my apps and it has worked beautifully for me (after many painstaking hours trying to figure it out). Here is exactly what I've used:
[[[self parentViewController] parentViewController] dismissModalViewControllerAnimated:YES];
if ([self respondsToSelector:#selector(presentingViewController)]) {
[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES]; // for IOS 5+
} else {
[self.parentViewController.parentViewController dismissModalViewControllerAnimated:YES]; // for pre IOS 5
}
If you have a dynamic UX and do not know how many parents to go to, you can use this recursive function to figure it out...
- (void) goHome
{
//Dismiss modal back to home page
int numberOfVcsToDismiss = [self findRootViewController:self];
[self dismissToRootVc:numberOfVcsToDismiss];
}
- (int) findRootViewController:(UIViewController*)vc
{
if(vc)
{
return 1 + [self findRootViewController:vc.presentingViewController];
}
return 0;
}
- (void) dismissToRootVc:(int)count
{
if(count == 1)
[self dismissViewControllerAnimated:YES completion:^{}];
if(count == 2)
[self.presentingViewController dismissViewControllerAnimated:YES completion:^{}];
if(count == 3)
[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:^{}];
if(count == 4)
[self.presentingViewController.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:^{}];
if(count == 5)
[self.presentingViewController.presentingViewController.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:^{}];
//etc....
}

Modal View Not Working

I am using the following code in my view controller and I want it to present another view controller called "chooserViewController" modaly
- (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated
{
[self presentModalViewController:chooserViewController animated:YES];
}
I am getting a compile error not recognizing "chooserViewController". Am I doing it wrong?
Update:
- (void)add:(id)sender
{
RoutineExerciseChooserViewController *routineExerciseChooserViewController = [[RoutineExerciseChooserViewController alloc] initWithNibName:#"RoutineExerciseChooserViewController" bundle: nil];
[self presentModalViewController:routineExerciseChooserViewController animated:YES];
[routineExerciseChooserViewController release];
}
You need to create chooserViewController:
- (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated {
ChooserViewController *chooserViewController = [[ChooserViewController alloc] initWithNibName:#"ChooserView" bundle: nil];
[self presentModalViewController:chooserViewController animated:YES];
[chooserViewController release];
}
If you're not loading from a nib, obviously you'll use a different way to create chooserViewController, but you have to do something to ensure it exists, and can then be presented.

The dealloc method is not called in the present modal view contrller

It is in My view controller
-(void)doctorsListAction
{
if(isFirst == YES)
{
[self getDoctorsListController];
[[self navigationController] presentModalViewController:doctorListViewNavigationController animated:YES];
[doctorListViewController release];
}
}
-(void)getDoctorsListController
{
//DoctorListViewController *doctorListViewController=[[[DoctorListViewController alloc]initWithNibName:nil bundle:nil]autorelease];
doctorListViewController=[[DoctorListViewController alloc]init];
doctorListViewNavigationController=[[UINavigationController alloc]initWithRootViewController:doctorListViewController];
doctorListViewController.doctorList=doctorList;
doctorListViewNavigationController.navigationBar.barStyle= UIBarStyleBlackOpaque;
[doctorListViewController release];
}
It is in DoctorListViewContrller
-(void)closeAction
{
printf("\n hai i am in close action*******************************");
//[doctorList release];
//[myTableView release];
//myTableView=nil;
printf("\n myTableView retainCount :%d",[myTableView retainCount]);
[[self navigationController] dismissModalViewControllerAnimated:YES];
}
//this method is not called I don't know why if it not called i will get memory issues
- (void)dealloc
{
printf("\n hai i am in dealloc of Doctor list view contrller");
[doctorList release];
[myTableView release];
myTableView=nil;
[super dealloc];
}
this method is not called I don't know
why if it not called i will get memory
issues
When exactly dealloc gets called (i.e. when the object is deallocated) shouldn't really matter to you. What matters is that you pair up each alloc with a release/autorelease. Which you are likely not doing.
The above code doesn't read very well and looks a bit "Java"-ish. Your "get" method doesn't actually return anything, which looks strange. But you normally wouldn't name a method "get___" anyway.
You're probably leaking memory in your getDoctorsListController method on this line:
doctorListViewNavigationController=[[UINavigationController alloc]initWithRootViewController:doctorListViewController];
Since you didn't define doctorListViewNavigationController in this method, and I assume you posted code that compiles, it is either a member (although not necessarily a property) of your class or a static variable somewhere. Which means it could already be pointing to an object. Which means when you assign a new alloc'ed object to it, the old one is lost (leaked).
Here's how you should refactor it.
- (void)doctorsListAction
{
if (isFirst == YES)
{
[self showDoctorsList];
}
}
- (void)showDoctorsList
{
DoctorListViewController* doctorListViewController = [[DoctorListViewController alloc] initWithNibName:nil bundle:nil];
doctorListViewController.doctorList = doctorList;
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:doctorListViewController];
navController.navigationBar.barStyle = UIBarStyleBlackOpaque;
[self.navigationController presentModalViewController:navController animated:YES];
[navController release];
[doctorListViewController release];
}
There might be a lot of other objects 'behind the scenes' that want to keep the DoctorListViewController around. If you just balance out your retains and releases, you should be ok.
Also in -(void)doctorsListAction, shouldn't [doctorListViewController release]; be [doctorListViewNavigationController release]; instead?