UIViewController的第二个实例被实例化,失去了对原始的初始化。为什么?

时间:2009-06-19 17:25:20

标签: iphone

我遇到以下代码问题。您可以创建TripDetailsController(UIViewController的子类),并使用initWithNibName方法初始化它。这个initWithNibName需要一个额外的参数(tripDetails),请参阅下面的TripDetailsController类的代码。变量td有一个值,当单步执行代码时,我检查了在执行initWithNibName方法时在tdController上设置了这个值。但是,在TripDetailsController.viewDidLoad方法(在调用pushViewController()时执行)中设置断点时,TripDetailsController的tripDetails属性为nil ?!? 使用调试器我发现我在initWithNibName方法中看到的tdController实例与我在viewDidLoad方法中看到的实例不同?怎么会?为什么有一个新的TripDetailsController实例和谁创建?

在这篇文章的最后,我包含了一个调用堆栈的转储,可能会给你一个提示,告诉你这个问题的原因。

代码:

// 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

欢迎任何建议。

格罗

4 个答案:

答案 0 :(得分:0)

听起来你没有保留tripDetails对象,所以它在你尝试使用之前就已经发布了。

答案 1 :(得分:0)

您应该发布调用initWithNibName:bundle:

的代码

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

答案 2 :(得分: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属性设置为retain? (而不是分配)。

答案 3 :(得分:0)

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

与原始代码的主要区别:

  • 不再在.xib文件中定义TripDetailsController
  • TripDetailsController不再从.xib文件加载,但初始化如下:

代码:

TripDetailsController *tdController = 
    [[TripDetailsController alloc] initWithStyle:UITableViewStyleGrouped];
  • TripDetailsController不再是UIViewController,而是UITableViewController的子类

因此我不得不稍微调整一下布局,但至少它现在有用了。

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

格罗