2

我正在构建一个带有自定义栏选项卡的简单应用程序,该选项卡ViewControllerUITableView位于另一个ViewController.

但是,每次我尝试在 tableview 上滚动时,都会出现exc_bad_access错误。我启用NSzombies并保护 malloc 以获取有关该问题的更多信息。

在控制台中我得到:

"message sent to deallocated instance 0x19182f20" 

分析后我得到:

#   Address             Category                    Event Type  RefCt     Timestamp Size    Responsible Library   Responsible Caller
56  0x19182f20          FirstTabBarViewController   Zombie      -1        00:16.613.309 0   UIKit                 -[UIScrollView(UIScrollViewInternal) _scrollViewWillBeginDragging]

这是发生错误的ViewController的一些代码:.h文件:

#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 文件:

#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

这个 FirstTabBarViewController 使用以下自定义 segue 加载到 MainViewController 中:

#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

Datacontroller 类只是一个包含字符串的简单 NSMutableArray。

我正在使用 ARC,所以我不明白内存管理错误来自哪里。有人有线索吗?

非常感谢任何帮助;)谢谢!

4

1 回答 1

0

好的...感谢您的代码示例...

请参阅UIStoryboardSegue 文档,当您perform在您的 中实现时customTabBarSegue,您最终负责设置 2 个 viewController 之间的正确关系。你有两种可能性:

  • 将 dst 设置为模态子项(然后 src 属于presentingViewControllerdst),在末尾添加以下代码perform[src presentViewController:dst animated:NO completion:nil];

  • 将 dst 设置为 src 的子 viewController - 添加此代码:[src addChildViewController:dst]; 在末尾perform,但是,您必须在某处将其删除,或以相同的方法删除其他子项....

这是一个实现

@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];

    // this container only show 1 viewController at a time, so we can remove previous ones
    for (UIViewController *vc in src.childViewControllers) {
        [vc.view removeFromSuperview];
        [vc removeFromParentViewController];
    }
    //then add the new View controller as child
    [src addChildViewController:dst];

}
@end

无论如何,您应该明确地更多地研究 UIViewController 包含...

于 2013-08-02T15:33:35.787 回答