Question

I am trying to build an iOS app in which I created a custom tab bar: In a UIView I have different buttons loading the content of a UIView in the same view controller.

In some views, I inserted a UITableView. The table loads just fine with all the cells get printed correctly except that when I scroll I get an EXC_BAD_ACCESS error. I enabled zombie to get more info and I get the following message: "FirstTabBarController responsToSelector]: message sent to deallocated instance 0x75d79d0

I can't figure out how to fix this.

Here is a bit more on the structure of the app: In the MainViewController, I have a UIView which gets data from different UIViewControllers to load the content to replicate a tabbar:

.h file:

#import <UIKit/UIKit.h>

@interface MainViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIView *placeholderView;
@property (weak, nonatomic) UIViewController *currentViewController;

@end

When I load with a custom segue my FirstTabBarViewController, I get the table which doesnt scroll:

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

@interface FirstTabBarViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>  {
    IBOutlet UITableView* tabBarTable;
}

@property (strong, nonatomic) IBOutlet UIView *mainView;
@property (strong, nonatomic) IBOutlet UITableView *tabBarTable;
@property (nonatomic, strong) DataController *messageDataController;

@end

.m file:

#import "FirstTabBarViewController.h"
#import "DataController.h"

@interface FirstTabBarViewController ()

@end

@implementation FirstTabBarViewController
@synthesize tabBarTable=_tabBarTable;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)awakeFromNib
{
    [super awakeFromNib];
    self.messageDataController=[[DataController alloc] init];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [self.messageDataController countOfList];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"mainCell";
    UITableViewCell *cell = [tableView
                             dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    };

    NSString *expenseAtIndex = [self.messageDataController
                                   objectInListAtIndex:indexPath.row];
    [[cell textLabel] setText:expenseAtIndex];
    return cell;
}


- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return NO;
}

@end

The DataController class is a simple NSMutableArray containing strings. The custom segue acts like this:

#import "customTabBarSegue.h"
#import "MainViewController.h"

@implementation customTabBarSegue

-(void) perform {
    MainViewController *src= (MainViewController *) [self sourceViewController];
    UIViewController *dst=(UIViewController *)[self destinationViewController];

    for (UIView *view in src.placeholderView.subviews){
        [view removeFromSuperview];
    }

    src.currentViewController =dst;
    [src.placeholderView addSubview:dst.view];



}
@end

Many thanks for your help, it is very much appreciated.

Was it helpful?

Solution

Check if you set your tab bar controller as your UIWindow's rootViewController in the app delegate. Otherwise it might not get retained and after the didFinishLaunching it would get released causing the EXC_BAD_ACCESS.

I have seen people use outdated templates for projects which still have the old variant where they only add the tab bar comtroller's view to the window. This does not work any more since iOS 6.

OTHER TIPS

in your code replace following Method:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"mainCell";
    UITableViewCell *cell = [tableView
                             dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    };

    NSString *expenseAtIndex = [self.messageDataController
                                   objectInListAtIndex:indexPath.row];
    [[cell textLabel] setText:expenseAtIndex];
    return cell;
}

with following Method:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        static NSString *CellIdentifier = @"mainCell";
        UITableViewCell *cell = [tableView
                                 dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil){
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        };

        NSString *expenseAtIndex = [[NSString alloc] initWithString:@"%@",[self.messageDataController objectInListAtIndex:indexPath.row]];
        [[cell textLabel] setText:expenseAtIndex];

        return cell;
    }

i hope this will help you.

@Arnuad

As stated in my previous post, TableView is getting out of scope and this is the exact case. I have found a solution for that which is working absolutely fine.

In your customTabBarSegue file, write the following code in the end of perform method :

dst.dashboardTable.delegate = src;
dst.dashboardTable.dataSource = src;

and implement datasource and delegate methods in MainViewController

Hope this will help you.

@Arnuad

Found another better solution.

Just make the property of currentViewController as strong instead of weak in MainViewController.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top