2009-06-19 74 views
0

我遇到以下代码的问题。正如你可以创建一个TripDetailsController(UIViewController的子类),并使用initWithNibName方法初始化这个TripDetailsController。这个initWithNibName需要一个额外的参数(tripDetails),参见下面的TripDetailsController类的代码。变量td具有一个值,并且在遍历代码时,我检查了在执行initWithNibName方法时在tdController上设置了此值。但是,在TripDetailsController.viewDidLoad方法(当调用pushViewController()时执行该方法)中设置断点时,TripDetailsController的tripDetails属性为nil?!? 使用调试器我发现我在initWithNibName方法中看到的tdController实例与我在viewDidLoad方法中看到的实例是不同的实例?怎么来的?为什么创建TripDetailsController的新实例以及由谁创建?UIViewController的第二个实例实例化,失去了在原始上完成的初始化。为什么?

在这篇文章的最后,我加入了一个调用栈的转储,也许这给了你一个提示这个问题的原因。

代码:

// Code from RootViewController.getTripDetails() (see stacktrace below) 
TripDetails td = ...; // td has a value 
// Push the detail view controller 
TripDetailsController *tdController = [[TripDetailsController alloc] initWithNibName:@"TripDetailsController" bundle:nil tripDetails:td]; 

      // Checked using the debugger that tdController.tripDetails is set 

[self.navigationController pushViewController:tdController animated:YES]; 
[tdController release]; 

代码:

@implementation TripDetailsController 

@synthesize tripDetails, expectedDurationLabel, normalDurationLabel; 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.navigationItem.title = @"Reis Details"; 
    expectedDurationLabel.text = [NSString stringWithFormat:@"%@", tripDetails.expectedDuration]; 
} 

- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle tripDetails:(TripDetails *)td { 
    self = [self initWithNibName:nibName bundle:nibBundle]; 
    self.tripDetails = td; // self.tripDetails has a value here! 
    [self.tripDetails retain]; 
    return self; 
} 

- (void)dealloc { 
    [self.tripDetails release]; 
    [super dealloc]; 
} 
@end 

alt text http://gerodt.homeip.net/stack.png

任何建议都欢迎。

+1

虽然无关,你不需要做[self.tripDetails保留]因为,据推测,这个属性被自动保留。 – 2009-06-19 18:43:47

回答

0

我找到了一种方法,通过遵循Apple的S impleDrillDown example的示例代码来实现它。

与我的原代码的主要区别:

  • TripDetailsController不再以文件的.xib
  • TripDetailsController不再加载定义。厦门国际银行文件,但初始化如下:

代码:

TripDetailsController *tdController = 
    [[TripDetailsController alloc] initWithStyle:UITableViewStyleGrouped]; 
  • TripDetailsController不再是一个UIViewController,但UITableViewController中

的子类,因此,我不得不调整布局有点,但至少现在起作用了。

看起来好像无法从XIB文件初始化视图控制器,然后将其推送到导航控制器。

0

这听起来像你不保留tripDetails对象,所以你尝试使用之前,它变得释放。

+0

我已经在initWithNibName方法中保留了tripDetails对象(参见上面的代码),并且现在还在创建tripDetails对象的代码中添加了一个保留。这没有效果。 我不知道这个问题是否保留了tripDetails对象本身,因为TripDetailsController实例的指针值在viewDidLoad和initWithNibName方法中是不同的。我期待问题出现在这个领域。为什么有两个TripDetailsController实例?我只创建一个。 – Gero 2009-06-19 18:23:56

+0

您不需要保留,因为属性(可能)保留了它。如果它由于某种原因而被释放,当你尝试访问一个释放对象而不是伊娃成为零时,你会遇到异常。 – 2009-06-19 18:46:04

0

您应该发布调用initWithNibName:bundle:的代码。

我的预感是你正在编程创建一个,但实际上正在使用的那个是在NIB文件中创建的。也许你的主视图NIB创建一个TripDetailsController作为选项卡视图或导航根。在这种情况下,initWithCoder:被调用而不是initWithNibName:bundle:,这将解释未初始化的td伊娃。

+0

上面包含调用initWithNameName:bundle:tripDetails的代码。这是第一个代码片段。其余的代码是TripDetailsController的实现。 – Gero 2009-06-19 18:25:44

0

等待,我已经看到了这一点之前:

而不是使一个自定义的初始化程序,使用标准之一,试试这个:

TripDetails td = ...; // td has a value 
TripDetailsController *tdController = [[TripDetailsController alloc] initWithNibName:@"TripDetailsController" bundle:[NSBundle mainBundle]]; 
[tdController setTripDetails:td] 

[self.navigationController pushViewController:tdController animated:YES]; 
[tdController release]; 

原来的答复: 在TripDetailsController接口,是thipDetails属性集保留? (而不是分配)。