Iphone UIViewController的第二个实例已实例化,取消了对原始对象的初始化。为什么?

Iphone UIViewController的第二个实例已实例化,取消了对原始对象的初始化。为什么?,iphone,Iphone,我对以下代码有问题。正如您所能看到的,一个TripDetailsController被创建为UIViewController的子类,这个子类用initWithNibName方法初始化。此initWithNibName接受一个额外参数tripDetails,请参阅下面的TripDetailsController类代码。变量td有一个值,在单步执行代码时,我检查了在执行initWithNibName方法时tdController上是否设置了该值。但是,在调用pushViewController时执行

我对以下代码有问题。正如您所能看到的,一个TripDetailsController被创建为UIViewController的子类,这个子类用initWithNibName方法初始化。此initWithNibName接受一个额外参数tripDetails,请参阅下面的TripDetailsController类代码。变量td有一个值,在单步执行代码时,我检查了在执行initWithNibName方法时tdController上是否设置了该值。但是,在调用pushViewController时执行的TripDetailsController.viewDidLoad方法中设置断点时,TripDetailsController的tripDetails属性为零?!? 使用调试器,我发现我在initWithNibName方法中看到的tdController实例与我在viewDidLoad方法中看到的实例不同?怎么会?为什么有一个TripDetailsController的新实例是由谁创建的

在这篇文章的末尾,我包含了一个调用堆栈转储,也许这会给你一个关于这个问题原因的提示

代码:

代码:

欢迎提出任何建议


Gero

听起来好像您没有保留tripDetails对象,所以在您尝试使用之前它会被释放。

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


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

等等,我以前见过:

使用标准初始值设定项并尝试以下操作,而不是自定义初始值设定项:

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属性是否设置为保留?而不是赋值。

我找到了一种方法,通过遵循苹果S的示例代码来让它工作

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

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

TripDetailsController不再是UIViewController,而是UITableViewController的子类 因此,我不得不稍微调整一下布局,但至少现在它可以工作了

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


Gero

我已经在initWithNibName方法中保留了tripDetails对象,请参见上面的代码,现在还在创建tripDetails对象的代码中添加了一个retain。这没有效果。我想知道问题是否在于保留tripDetails对象本身,因为在viewDidLoad和initWithNibName方法中TripDetailsController实例的指针值不同。我认为问题出在那一方面。为什么TripDetailsController有两个实例?我只创建了一个。您不需要retain,因为属性可能会保留它。如果它由于某种原因被释放,当您尝试访问一个解除分配的对象而不是ivar变为nil时,您会遇到一个异常。上面包含了调用initWithNameName:bundle:tripDetails的代码。这是第一个代码片段。代码的其余部分是TripDetailsController的实现。第二个注意:nitWithNameName:bundle:tripDetails确实会被调用,因为它在那里设置了一个断点并停止了执行。这确实非常奇怪。查看您的代码,我看不出getTripDetails中的tdController如何与接收viewDidLoad的实例不同。我能想到的唯一一件事是调试器实际上正在执行旧版本的代码。。。我在更改生成目标的产品ID时遇到过这种情况。对于UIViewController,如果在初始化后不使用viewDidLoad进行设置或在外部执行,有时会出现奇怪的行为。记住这一点后,我编辑了我的答案。我想这就是为什么苹果告诉你使用viewDidLoad进行额外设置的原因。在执行pushViewController之前,我添加了一个对viewDidLoad的显式调用,在这种情况下,调用viewDidLoad是可以的。但是,pushViewController也会触发viewDidLoad,然后TripDetailsController的实例再次不同,tripDetails属性为零。虽然不相关,但您不需要执行[self.tripDetails retain],因为据推测,该属性将自动保留。这是我最初的方法,与我在原始帖子中列出的方法具有相同的效果。“tdController”的指针值与TripDetailsController.viewDidLoad方法中的“self”值不同,并且viewDidLoad中的tripDetails属性为零。是,tripDetails属性设置为保留在
对于这个类来说,e.h文件应该无关紧要,但是您是否正在执行ifself=[super initWithNib:bundle:]?奇怪的是,自我不是同一个对象。我会尝试在另一个项目中重写这段代码,看看会发生什么。听起来你有一些很难找到的bug。
@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
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 *tdController = 
    [[TripDetailsController alloc] initWithStyle:UITableViewStyleGrouped];