PDA

View Full Version : pushViewController causing leak?




led1973
Apr 7, 2011, 10:34 PM
I apologize for my issue being too “elementary” and if my title is misleading. I am very new to iPhone programming. I only know what I’ve read and seen and my first app isn’t working. I'm only trying to transition from view to view sequentially.

I have four ViewController files: RootViewController.xib, SecondList.xib, AddNewList.xib, AddNewItem.xib

Of course, RootViewController.xib loads first. There is a plus button that “pushViewController” AddNewList.xib. There is a Round Rect button that pushViewController SecondList.xib and lastly, a plus button pushViewControllers AddNewItem.xib.

The “lastly” is where the app dies. When I hit the last plus button, the program gets a “GDB: Program received signal: SIGABRT”. I think it’s caused by a memory leak. When debugging, I noticed that the method “(void)dealloc;” never gets executed.

Am I correct that I have a memory leak? If it is a leak, I am assuming that if the dealloc method gets executed then the leak would go away. How do I “cause” the dealloc method to get executed. If not a leak, what do you think?

Any suggestions would be greatly appreciated. Thanks!

My code are below:

RootViewController.h:

#import <UIKit/UIKit.h>
#import "AddNewSecondList.h"

@interface RootViewController : UITableViewController {
AddNewSecondList *addSecondListController;
NSArray *mainList;
}

@property (nonatomic,retain) AddNewSecondList *addSecondListController;
@property (nonatomic,retain) NSArray *mainList;

-(void)addSecondList;

@end


RootViewController.m:

@implementation RootViewController

@synthesize addSecondListController;
@synthesize mainList;

- (void)viewDidLoad {
self.navigationItem.title = @"Main";
[super viewDidLoad];

UIBarButtonItem *plusButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addSecondList)];
self.navigationItem.rightBarButtonItem = plusButton;
self.navigationItem.leftBarButtonItem = self.editButtonItem;
}

- (void)addSecondList {
if (self.addSecondListController == nil) {
AddNewSecondList *SecondListViewController = [[AddNewSecondList alloc] initWithNibName:@"AddNewSecondList"
bundle:nil];
self.addSecondListController = SecondListViewController;
[SecondListViewController release];
[self.navigationController pushViewController:self.addSecondListController animated:YES];
}
else {
[self.navigationController pushViewController:self.addSecondListController animated:YES];
}
}

- (void)dealloc {
[addSecondListController dealloc];
[mainList dealloc];
[super dealloc];
}
@end


AddNewSecondList.h:

#import <UIKit/UIKit.h>
#import "SecondList.h"

@interface AddNewSecondList : UIViewController {
SecondList *newSecondListController;
}

@property (nonatomic,retain) SecondList *newSecondListController;

- (IBAction) addndisplayNewSecondList:(id) sender;

@end


AddNewSecondList.m:

@implementation AddNewSecondList

@synthesize amount;
@synthesize newSecondListController;

- (IBAction) addndisplayNewSecondList:(id) sender {
if (self.newSecondListController == nil) {
SecondList *SecList = [[SecondList alloc]
initWithNibName:@"SecondList"
bundle:nil];
self.newSecondListController = SecList;
[SecList release];
[self.navigationController pushViewController:self.newSecondListController animated:YES];
}
else {
[self.navigationController pushViewController:self.newSecondListController animated:YES];
}
}

- (void)viewDidLoad {
self.navigationItem.title = @"New Second List";

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton;
[backButton release];
[super viewDidLoad];
}

- (void)dealloc {
[newSecondListController dealloc];
[super dealloc];
}
@end


SecondList.h:

#import <UIKit/UIKit.h>
#import "AddNewItem.h"

@interface SecondList : UIViewController {
AddNewItem *AddNewItemViewController;
}

@property (nonatomic,retain) AddNewItem *AddNewItemViewController;

- (void)addNewListItem:(id) sender;
@end


SecondList.m:

@implementation SecondList

@synthesize AddNewItemViewController;

- (void)viewDidLoad {

self.navigationItem.title = @"Second List";

UIBarButtonItem *plusButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addNewPurchase)];
self.navigationItem.rightBarButtonItem = plusButton;
self.navigationItem.leftBarButtonItem = self.editButtonItem;
[super viewDidLoad];
}

- (void)addNewPurchase:(id) sender {
if (self.AddNewItemViewController == nil) {
AddNewItem *newItem = [[AddNewItem alloc]
initWithNibName:@"AddNewItem"
bundle:nil];
self.AddNewItemViewController = newItem;
[newItem release];
[self.navigationController pushViewController:self.AddNewItemViewController animated:YES];
}
else {
[self.navigationController pushViewController:self.AddNewItemViewController animated:YES];
}
}

- (void)dealloc {
[AddNewItemViewController dealloc];
[super dealloc];
}



dantastic
Apr 8, 2011, 02:29 AM
What you can do it enable breakpoints and when it crashes you can have a look in the debugger - it will tell you on what line the app crashed on.


AddNewSecondList *SecondListViewController = [[AddNewSecondList alloc] initWithNibName:@"AddNewSecondList"
bundle:nil];
self.addSecondListController = SecondListViewController;
[SecondListViewController release];
[self.navigationController pushViewController:self.addSecondListController animated:YES];


Why do you retain a reference the the navigation controller created here? If you have processing going on in this view you should move that to the Model layer and just create the view each time, like:

AddNewSecondList *secondListViewController = [[AddNewSecondList alloc] initWithNibName:@"AddNewSecondList"
bundle:nil];
[self.navigationController pushViewController:secondListController animated:YES];
[secondListController release];

idelovski
Apr 8, 2011, 03:44 AM
A leak...

- (void)viewDidLoad {
self.navigationItem.title = @"Main";
[super viewDidLoad];

UIBarButtonItem *plusButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addSecondList)];
self.navigationItem.rightBarButtonItem = plusButton;
self.navigationItem.leftBarButtonItem = self.editButtonItem;
}

Add [plusButton release]; at the end.

Sykte
Apr 8, 2011, 06:44 AM
RootViewController.m:

@implementation RootViewController

@synthesize addSecondListController;
@synthesize mainList;

- (void)viewDidLoad {
self.navigationItem.title = @"Main";
[super viewDidLoad];

UIBarButtonItem *plusButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addSecondList)];
self.navigationItem.rightBarButtonItem = plusButton;
self.navigationItem.leftBarButtonItem = self.editButtonItem;
}

- (void)addSecondList {
if (self.addSecondListController == nil) {
AddNewSecondList *SecondListViewController = [[AddNewSecondList alloc] initWithNibName:@"AddNewSecondList"
bundle:nil];
self.addSecondListController = SecondListViewController;
[SecondListViewController release];
[self.navigationController pushViewController:self.addSecondListController animated:YES];
}
else {
[self.navigationController pushViewController:self.addSecondListController animated:YES];
}
}

- (void)dealloc {
[addSecondListController dealloc];
[mainList dealloc];
[super dealloc];
}
@end



AddNewSecondList.m:

@implementation AddNewSecondList

@synthesize amount;
@synthesize newSecondListController;

- (IBAction) addndisplayNewSecondList:(id) sender {
if (self.newSecondListController == nil) {
SecondList *SecList = [[SecondList alloc]
initWithNibName:@"SecondList"
bundle:nil];
self.newSecondListController = SecList;
[SecList release];
[self.navigationController pushViewController:self.newSecondListController animated:YES];
}
else {
[self.navigationController pushViewController:self.newSecondListController animated:YES];
}
}

- (void)viewDidLoad {
self.navigationItem.title = @"New Second List";

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton;
[backButton release];
[super viewDidLoad];
}

- (void)dealloc {
[newSecondListController dealloc];
[super dealloc];
}
@end


SecondList.m:

@implementation SecondList

@synthesize AddNewItemViewController;

- (void)viewDidLoad {

self.navigationItem.title = @"Second List";

UIBarButtonItem *plusButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addNewPurchase)];
self.navigationItem.rightBarButtonItem = plusButton;
self.navigationItem.leftBarButtonItem = self.editButtonItem;
[super viewDidLoad];
}

- (void)addNewPurchase:(id) sender {
if (self.AddNewItemViewController == nil) {
AddNewItem *newItem = [[AddNewItem alloc]
initWithNibName:@"AddNewItem"
bundle:nil];
self.AddNewItemViewController = newItem;
[newItem release];
[self.navigationController pushViewController:self.AddNewItemViewController animated:YES];
}
else {
[self.navigationController pushViewController:self.AddNewItemViewController animated:YES];
}
}

- (void)dealloc {
[AddNewItemViewController dealloc];
[super dealloc];
}


Never send the message dealloc to an object, with the exception of super. To free the object "release your ownship" you would send a release message to the object.


Edit:
Here are a few other notes.

RootViewController has a memory leak in viewDidLoad.
RootViewController addSecondList has multiple problems. Why are you keeping the addSecondListController around in a property, let the navigationController hold on to it. This goes for the other viewControllers as well. Another problem I see is double retaining properties.

I have more, once you fix these post your code and we can go thru it. Also some of these changes can be cascaded to your other viewControllers.

Make sure you understand why you are changing these. Look at the apple docs or ask questions per change.