Второй экземпляр UIViewController создан, теряя инициализации, сделанные на оригинале. Зачем? - PullRequest
0 голосов
/ 19 июня 2009

У меня проблема со следующим кодом. Как вы можете создать TripDetailsController (подкласс UIViewController), и этот инициализируется с помощью метода initWithNibName. Этот initWithNibName принимает дополнительный аргумент (tripDetails), см. Код класса TripDetailsController ниже. Переменная td имеет значение, и при пошаговом выполнении кода я проверял, что это значение было установлено в tdController при выполнении метода initWithNibName. Однако при установке точки останова в методе TripDetailsController.viewDidLoad (который выполняется при вызове pushViewController ()) атрибут tripDetails в TripDetailsController равен нулю? Используя отладчик, я обнаружил, что экземпляр tdController, который я вижу в методе initWithNibName, отличается от экземпляра, который я вижу в методе 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

альтернативный текст http://gerodt.homeip.net/stack.png

Любые предложения приветствуются.

Геро

Ответы [ 4 ]

0 голосов
/ 21 июня 2009

Я нашел способ заставить его работать, следуя примеру кода из примера от S ImpleDrillDown от Apple.

Основные отличия от моего исходного кода:

  • TripDetailsController больше не определяется в файле .xib
  • TripDetailsController больше не загружается из файла .xib, но инициализируется следующим образом:

Код:

TripDetailsController *tdController = 
    [[TripDetailsController alloc] initWithStyle:UITableViewStyleGrouped];
  • TripDetailsController больше не является UIViewController, а подклассом UITableViewController

В результате мне пришлось немного настроить макет, но, по крайней мере, теперь он работает.

Похоже, что невозможно инициализировать контроллер представления из файла XIB и затем передать его на контроллер навигации.

Геро

0 голосов
/ 19 июня 2009

Вы должны опубликовать код, который вызывает initWithNibName:bundle:.

Я догадываюсь, что вы создаете один программно, но тот, который фактически используется, создается в файле NIB. Может быть, ваш основной вид NIB создает TripDetailsController в виде представления вкладки или корня навигации. В этом случае вместо initWithNibName:bundle: вызывается initWithCoder:, что объясняет неинициализированный td ivar.

0 голосов
/ 20 июня 2009

Подождите, я видел это раньше:

Вместо создания пользовательского инициализатора, используйте стандартный и попробуйте это:

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 установлено для сохранения? (и не присваивать).

0 голосов
/ 19 июня 2009

Похоже, вы не сохраняете объект tripDetails, поэтому он освобождается до того, как вы попытаетесь его использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...