2

按照 Scott Sherwood 的本教程(http://www.scott-sherwood.com/ios-5-creating-a-custom-side-tabbar-using-storyboards-and-custom-segues/),我创建了一个使用子视图加载其他视图的自定义标签栏。一切都很顺利,我对结果非常满意。但是,当我将表格视图添加到“标签页”之一并将其连接到数据源时,应用程序崩溃了。

我正在使用 ARC 并打开了僵尸,所以我的控制台告诉我一条消息已发送到我的表视图的已释放实例。我不知道如何保留表格视图,以便显示我的数据。这只是我的第二个应用程序,我对故事板和高级视图控制器还不太熟悉。我错过了什么?

这是我的自定义选项卡视图控制器:

CustomTabBarViewController.h

@interface CustomTabBarViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>{

}

@property(weak,nonatomic)UIViewController *currentViewController;
@property(weak,nonatomic)IBOutlet UIView *placeholder;
@property (weak, nonatomic) IBOutlet UIImageView *tabIndicator;
@property (weak, nonatomic) IBOutlet UIImageView *headerBacker1;
@property (weak, nonatomic) IBOutlet UIImageView *headerBacker2;



@end

CustomTabBarViewController.m

#import "CustomTabBarViewController.h"

@interface CustomTabBarViewController ()

@property (weak, nonatomic) IBOutlet UIView *buttons;

@end

@implementation CustomTabBarViewController

@synthesize currentViewController;
@synthesize placeholder;
@synthesize buttons;
@synthesize tabIndicator;
@synthesize headerBacker1;
@synthesize headerBacker2;


- (void)viewDidLoad
{
    [super viewDidLoad];
    [self performSegueWithIdentifier:@"ProductSegue" sender:[self.buttons.subviews objectAtIndex:0]];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidUnload
{
    [self setTabIndicator:nil];
    [self setHeaderBacker1:nil];
    [self setHeaderBacker2:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if([segue.identifier isEqualToString:@"ProductSegue"]
       || [segue.identifier isEqualToString:@"ContactSegue"]
       || [segue.identifier isEqualToString:@"CategoryPage"]){


        if([segue.identifier isEqualToString:@"ContactSegue"]){

            [UIView animateWithDuration:0.25f delay:0.0f options:UIViewAnimationOptionCurveEaseOut animations:^{
                [tabIndicator setCenter:CGPointMake(614, 108)];
                [headerBacker1 setCenter:CGPointMake(1024, 48)];
                [headerBacker2 setCenter:CGPointMake(1024, 789)];
            } completion:nil];

        }else{
            [UIView animateWithDuration:0.25f delay:0.0f options:UIViewAnimationOptionCurveEaseOut animations:^{
                [tabIndicator setCenter:CGPointMake(499, 108)];
                [headerBacker1 setCenter:CGPointMake(341, 48)];
                [headerBacker2 setCenter:CGPointMake(341, 789)];
                } completion:nil];

        }
    }
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}

@end

以及加载到选项卡中的页面,其中包含表格视图:(注意*:此页面链接为情节提要中的表格视图数据源和表格视图委托)

ProductListViewController.h

#import <UIKit/UIKit.h>

@interface ProductListViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>


@property (strong, nonatomic) NSMutableArray *maTheData;


@end

ProductListViewController.m

#import "ProductListViewController.h"

@interface ProductListViewController ()

@end

@implementation ProductListViewController


@synthesize maTheData;

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


- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"viewDidLoad");
    if (!maTheData) {
        maTheData = [[NSMutableArray alloc] initWithObjects:@"Comets", @"Asteroids", @"Moons", nil];
    }
}

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


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


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [maTheData count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"categoryTableCell"];
    UILabel *lblName = (UILabel *)[cell viewWithTag:100];
    [lblName setText:[maTheData objectAtIndex:[indexPath row]]];

    return cell;
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.
    /*
     <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
     [self.navigationController pushViewController:detailViewController animated:YES];
     */
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    //return UIInterfaceOrientationIsLandscape(interfaceOrientation);
    return interfaceOrientation == UIInterfaceOrientationLandscapeRight;

}

@end

谢谢你的想法。

4

3 回答 3

0

据我从您提供的链接中可以看出,您要连接的控制器应该由 currentViewController 指向。所以,问题在于这个声明:

@property(weak,nonatomic)UIViewController *currentViewController;

这需要强大,而不是弱。IBOutlets 弱是可以的,因为指向的对象是另一个视图的子视图,该视图持有对它们的强引用。但是, currentViewController 应该很强大,以防止您的控制器被释放(没有其他东西对它有很强的引用)。我从链接中看到他在 perform 方法中将 currentViewController 设置为 segue 的目标控制器——如果你这样做,并且你将声明更改为 strong,你应该没问题。

于 2013-04-23T02:45:27.033 回答
0
@property (nonatomic, strong) IBOutlet UITableView *tableView;

将此属性与情节提要中的 tableview 连接。这应该会阻止 tableview 处理,因为视图控制器有一个强指针。从调试点开始在您认为导致错误的区域放置断点以定位代码中断的行。然后您可以更深入地调查错误。我希望这有帮助。

于 2013-04-22T23:26:48.093 回答
0

我猜你遇到的问题是因为你有弱属性而不是强属性,特别是对于你的 currentViewController。尝试将它们全部更改为强,看看您是否仍然有问题。

摘自:Objective-C 中的弱和强属性设置器属性

弱(iOS4 = unsafe_unretained)

  • 它说“只要其他人强烈指出就保留它”与分配相同,不保留或释放
  • “弱”引用是您不保留的引用。
  • 我们通常对 IBOutlets(UIViewController 的 Childs)使用weak。这是因为子对象只需要与父对象一样存在。
  • 弱引用是不保护被引用对象不被垃圾收集器收集的引用。
  • 弱本质上是赋值,一个未保留的属性。除了当对象被释放时,弱指针自动设置为 nil
于 2013-04-22T21:39:32.617 回答