2013-05-20 5 views
0

У меня есть следующий код в viewController. У меня есть вид NavigationController в представлении (который является детским представлением - код для родителя работает нормально)Методы загрузки ViewController, вызываемые при исчезновении представления?

Что происходит, когда я выбираю опцию на родительском элементе, загружается этот диспетчер viewController. Пользователь может выбрать опцию из дочернего viewController для открытия PDF-файла с помощью DocumentInteractionController (который отлично работает).

Проблема заключается в том, что когда я пытаюсь вернуться к родительскому viewController, сообщения отправляются дочернему viewController, как будто он все еще выделен. Я видел что-то подобное, когда я его настраивал, поскольку было несколько вызовов методов в childController.

Любые мысли о том, что я делаю неправильно?

#import "DetailViewController.h" 

@interface DetailViewController() 

@end 

@implementation DetailViewController 

@synthesize node; 
@synthesize replies; 
@synthesize docController; 

- (void) viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [self.tableView reloadData]; 
    [self.tableView setContentOffset:CGPointZero animated:NO]; 
} 

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

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self.docController init]; 
    // Do any additional setup after loading the view from its nib. 
} 

- (void) dealloc 
{ 
    [self.docController release]; 
    [super dealloc]; 
} 

- (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 
{ 
    if (self.replies == nil) 
    { 
     self.replies = [[NSArray alloc] init]; 
     self.actions = [[NSArray alloc] init]; 
    } 
    if(self.replies.count == 0) 
    { 
     self.replies = [self.node nodesForXPath:@"./question/reply/text" error:nil]; 
     self.actions = [self.node nodesForXPath:@"./question/reply/response/action" error:nil]; 
    } 

    return self.replies.count; 
} 

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"QuestionCell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) 
    { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
    } 

    // Get the object to display and set the value in the cell 
    NSString *cellText = [[replies objectAtIndex:indexPath.row] stringValue]; 
    cell.textLabel.text = cellText; 
    return cell; 
} 

- (void) showOptionsMenu:(NSString *) fileName 
{ 

    NSString *fileToOpen = [[NSBundle mainBundle] pathForResource:fileName ofType:@"pdf"]; 
    NSURL *fileURL = [NSURL fileURLWithPath:fileToOpen]; 

    self.docController = [self setupControllerWithURL:fileURL usingDelegate:self]; 

    bool didShow = [self.docController presentOptionsMenuFromRect:CGRectMake(0, 0, 150, 150) inView: self.view animated:YES]; 

    if(!didShow) 
    { 
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"Sorry, app not found" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
     [alert show]; 
    } 

} 

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSString *action = [[self.actions objectAtIndex:indexPath.row] stringValue]; 
    [self showOptionsMenu:action]; 
} 

- (UIDocumentInteractionController *) setupControllerWithURL: (NSURL *) fileURL usingDelegate:(id <UIDocumentInteractionControllerDelegate>) interactionDelegate 
{ 
    UIDocumentInteractionController *interactionController = [UIDocumentInteractionController interactionControllerWithURL:fileURL]; 
    interactionController.delegate = interactionDelegate; 
    return interactionController; 
} 


@end 

EDIT

Добавление кода для контроллера представления родительского ... может быть, есть что-то я делаю неправильно там? Я использую GDataXML загрузить Q & приложение на основе содержимого файла XML ...

@implementation ViewController 

@synthesize currentReply; 
@synthesize questions; 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self setUpQuestions]; 
} 

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

- (void)dealloc 
{ 
    [super dealloc]; 
} 

- (void) setUpQuestions 
{ 
    // create and init NSXMLParser object 

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"query" ofType:@"xml"]; 
    NSData *xml_data = [[NSData alloc] initWithContentsOfFile:filePath]; 
    NSError *error; 
    GDataXMLDocument *xmlDoc = [[GDataXMLDocument alloc] initWithData:xml_data options:0 error:&error]; 

    NSArray *rootDataArray = [xmlDoc.rootElement nodesForXPath:@"//query" error:nil]; 
    for (GDataXMLElement *rootDataElement in rootDataArray) 
    { 
     // Allocate the query object 
     self->query = [[[Query alloc] init] autorelease]; 

     // Name 
     NSArray *query_title = [rootDataElement elementsForName:@"text"]; 
     if (query_title.count > 0) 
     { 
      GDataXMLElement *queryTitle = (GDataXMLElement *) [query_title objectAtIndex:0]; 

      self->query.queryTitle = [[[NSString alloc] initWithString:queryTitle.stringValue] autorelease]; 
     } 


     NSArray *query_first_question = [rootDataElement elementsForName:@"question"]; 
     NSArray *replies = [NSArray alloc]; 
     questions = [[NSMutableArray alloc] init]; 
     if(query_first_question.count == 1) 
     { 
      GDataXMLElement *fq = (GDataXMLElement *) [query_first_question objectAtIndex:0]; 
      replies = [fq elementsForName:@"reply"]; 
      for (GDataXMLElement *replyElement in replies) 
      { 
       [questions addObject:replyElement]; 
      } 
     } 
    } 
} 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    // Only one section. 
    return 1; 
} 

- (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection:(NSInteger)section 
{ 
    switch(section) 
    { 
     case 0: 
      return questions.count; 
      break; 
     case 1: 
      return 1; 
      break; 
    } 

} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *CellIdentifier = @"QuestionCell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) 
    { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
     cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; 
    } 

    // Get the object to display and set the value in the cell. 
    GDataXMLElement *questionAtIndex = questions[indexPath.row]; 
    NSString *cellText = [[[questionAtIndex elementsForName:@"text"] objectAtIndex:0] stringValue]; 
    cell.textLabel.text = cellText; 
    //cell.textLabel.text = [[questionAtIndex elementsForName:@"text"] objectAtIndex:0]; 
    return cell; 
} 


- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    //NSMutableString *msg = [NSMutableString new]; 
    //[msg appendString:@"You selected row: "]; 
    //[msg appendString:[NSString stringWithFormat:@"%i",indexPath.row]]; 

    //UIAlertView *alertMsg = [[UIAlertView alloc] initWithTitle:@"Row Selected" message:msg delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; 

    //[alertMsg show]; 
    if (questions != nil) 
    { 
     GDataXMLElement *selectedReply = (GDataXMLElement *) [questions objectAtIndex:indexPath.row]; 
     DetailViewController *dvc = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil]; 
     dvc.node = selectedReply; 
     [self.navigationController pushViewController:dvc animated:YES]; 
     [dvc release]; 
    } 
} 

EDIT

Я попытался профилирование и ищет зомби, но когда авария происходит, нет объектов зомби, помеченных. Он выдает следующее сообщение об ошибке в консоли:

[UIView _forgetDependentConstraint:]: message sent to deallocated instance 0x1e8ab810 
+0

Каковы отправленные сообщения или методы, вызываемые дочерним элементом viewController? –

+0

Я пытаюсь понять это - в выходном окне есть какой-то вывод, но он не сообщает мне отправленное сообщение. Это определенно похоже, что это звонок обратно в ребенка. Для записи я не использую ARC. – Tim

+0

Похоже, есть призыв к _forgetDependentConstraint, но я не могу понять, откуда он ... – Tim

ответ

1

Я видел эту проблему еще раньше !!!

Ответ:Turn Off "AutoLayout".

Я предполагаю, что ошибка произошла из-за новой функции в ios называется AutoLayout. Похоже, что компилятор создал несколько объектов NSLayoutConstraint, и по какой-то причине объекты были выпущены больше, чем нужно.Deletion and Re-Creation, заставляет Xcode перестроить ограничения. Но я не уверен на 100%.

Попробуйте Un-Check "AutoLayout", если это может решить вашу проблему.

+0

похоже, что это стоит того. Где опция AutoLayout? (Я относительно новичок в XCode) – Tim

+0

@Tim: здесь: http://www.goodbyehelicopter.com/2012/02/arggh-xcode-4-3-auto-layout-is-on-by-default- как-к-выключать-автоматически-макет/ – Bhavin

+0

В этом была проблема! Теперь мой код работает так, как ожидалось! Спасибо, Вин! – Tim

0

Ваш код DetailViewController прекрасно - на самом деле не в порядке, так как вы протечки self.replies и self.actions, и [self.docController INIT] очень странно и, вероятно, неправильно (всегда выделяйте и объединяйте вместе), но код жизненного цикла на этом конце выглядит отлично. Проблема почти наверняка находится в контроллере родительского представления (или, возможно, в контроллере документов, если вы создаете цикл сохранения там). Если контроллер родительского представления удерживает указатель на контроллере подробного представления, он фактически не будет освобожден, и доступ к представлению или любому его свойству приведет к вызову -viewDidLoad снова.

0

Из того, что я понял, ваш контроллер родительского вида устанавливает узел здесь:

dvc.node = selectedReply; 

и никогда не было освобожден от вашего DetailViewController.

Я предполагаю, что ваш GDataXMLElement в заголовке DetailViewController задан как «сохранить».

И есть некоторые проблемы, связанные с утечкой, как указал икодестаф.

Смежные вопросы