1

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.

4

4 回答 4

0

@Arnuad

找到了另一个更好的解决方案。

只需在MainViewController中将currentViewController的属性设为强而不是弱即可。

于 2013-08-20T20:16:35.240 回答
0

@Arnuad

正如我在上一篇文章中所说,TableView 超出了范围,这就是确切的情况。我已经找到了一个绝对可以正常工作的解决方案。

在您的customTabBarSegue文件中,在perform方法的末尾编写以下代码:

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

并在MainViewController中实现数据源和委托方法

希望这会帮助你。

于 2013-08-20T19:42:30.040 回答
0

检查您是否在应用程序委托中将标签栏控制器设置为 UIWindow 的 rootViewController。否则它可能不会被保留,并且在 didFinishLaunching 之后它会被释放,从而导致 EXC_BAD_ACCESS。

我看到人们使用过时的模板来处理仍然具有旧变体的项目,他们只将标签栏控制器的视图添加到窗口中。自 iOS 6 以来,这不再有效。

于 2013-08-20T20:31:26.500 回答
0

在您的代码中替换以下方法:

- (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;
}

使用以下方法:

- (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;
    }

我希望这能帮到您。

于 2013-08-01T10:52:10.083 回答