0

I'm trying to add a UIViewController subview, and then upon clicking a button close it. My current code does the job, I'm just not sure if it will leak or cause any problems.

So first I add the subview

-(IBAction)openNewView:(id)sender{
   // start animation
   [UIView beginAnimations:@"CurlUp" context:nil];
   [UIView setAnimationDuration:.3];
   [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
   [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];

   // add the view
   newViewController* newVC = [[newViewController alloc] initWithNibName:@"newViewController" bundle:[NSBundle mainBundle]];
   [self.view addSubview:newVC.view];

   [UIView commitAnimations]; 
}

Then in newViewController.m I have the function to remove it

-(IBAction)closeNewView:(id)sender{
   // start animation
   [UIView beginAnimations:@"curldown" context:nil];
   [UIView setAnimationDelegate:self];
   [UIView setAnimationDuration:.3];
   [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
   [UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.view.superview cache:YES];

   // close dialog
   [self.view removeFromSuperview];
   [UIView commitAnimations];

   [self.view release];
}

Like I said this works, however when I Analyze the code, it tells me:

Potential leak of an object allocated on line X and stored into 'newViewController' for:

newViewController* newVC = [[newViewController alloc] initWithNibName:@"newViewController" bundle:[NSBundle mainBundle]];

and

Incorrect decrement of the reference count of an object that is not owned at this point by the caller for [self.view release];

If I autorelease the viewController instead of [self.view release] it crashes upon removing (also if I release the view after adding it) with: -[FirstViewController performSelector:withObject:withObject:]: message sent to deallocated instance 0xd21c7e0

If I call [newVC release] in either viewControllers dealloc it fails to build.

Hopefully I'm not asking a fairly obvious question, but what is the correct way to add and remove viewControllers?

Kevin Schildhorn
  • 197
  • 2
  • 16

1 Answers1

0

What IOS version are you using? You should probably go ahead and switch over to ARC if you're using 5.0 so you don't have to deal with [release] calls yourself.

If you still want or need to stick with manual memory management: the reason dealloc fails to build if you try to release newVC is because that pointer is scoped to the function openNewView. Make it a class member and you'll be able to release it.

@implementation WhateverItsCalled {
  newViewController *newVC;
}

- ( IBAction ) openNewView: (id)sender {
...
  newVC = [ [ newViewController alloc ] initWithNibNamed:...
}

- ( void ) dealloc {
  [ newVC release ];
}

And yes, if you're not using ARC, every "alloc" must be paired with a corresponding "release".

Also I must ask - why are you using a view controller here at all? If you just want a view, you can load the view from a NIB with [ [ NSBundle mainBundle ] loadNibNamed] and list [self] as the file's owner. This will set all of your references (including the view you want) and you won't have to instantiate (what looks like) a superfluous view controller.

Joshua Davies
  • 981
  • 9
  • 16
  • This is my second app really, and first one with more than one view, so I'm pretty new at this. I didn't think to use just a nib I guess. Anyway I turned on ARC in my build settings, cleaned up all the releases and what not, and it comes up with `[newViewController performSelector:withObject:withObject:]: message sent to deallocated instance 0x6b34c70`. if I change it to `@interface newViewController : UIView {` and call `[[NSBundle mainBundle] loadNibNamed:@"dateViewController" owner:self options:nil];` (which is probably wrong on my half) it immediately SIGABRT's in Main.m – Kevin Schildhorn Apr 18 '12 at 19:09
  • Where do you get the "message sent to deallocated instance" error? Set an exception breakpoint (Cmd+6 to show the breakpoint view, "+" in the lower-left corner) to see exactly where this is coming from. – Joshua Davies Apr 18 '12 at 19:18
  • Most likely, you're getting the SIGABRT because there's an outlet named in your NIB that doesn't have a corresponding property in "self". Go to the NIB, click on the "files owner" placeholder, and switch to the outlet view (Cmd+Option+6). Every variable named there must have a corresponding property in "self" when the NIB is loaded. (You probably have similar properties in the view controller itself). – Joshua Davies Apr 18 '12 at 19:20
  • I added the exception breakpoint, however it never came up for the "message sent to deallocated instance" error. It did however come up when I switched back to the UIView, on the `[[NSBundle mainBundle] loadNibNamed:@"dateViewController" owner:self options:nil];`line, even after I checked the outlet view. It also comes up with at warning in the console. warning: Attempting to create USE_BLOCK_IN_FRAME variable with block that isn't in the frame. – Kevin Schildhorn Apr 18 '12 at 20:05