ViewController在视图消失时调用的加载方法?

时间:2013-05-20 13:34:34

标签: objective-c uiviewcontroller

我在viewController中有以下代码。我在视图上有一个NavigationController(这是子视图 - 父代码正常工作)

当我在父节点上选择一个选项时会发生这种情况,这个viewController会加载。用户可以从子viewController中选择一个选项,用DocumentInteractionController打开一个PDF文件(工作正常)。

问题是当我尝试回到父viewController时,消息被发送到子viewController,就像它仍然被分配一样。我在设置它时看到类似的东西,因为在子viewController中有多个方法调用。

对我做错了什么的想法?

#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

修改

添加父视图控制器的代码...也许我在那里做错了什么?我正在使用GDataXML根据XML文件的内容加载Q&amp; A应用程序......

@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];
    }
}

修改

我尝试过分析并寻找僵尸,但是当崩溃发生时,没有标记的僵尸对象。它在控制台中抛出以下错误:

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

3 个答案:

答案 0 :(得分:1)

  

我之前也见过这个问题!!!

答案: Turn Off "AutoLayout".

我猜测由于名为ios的{​​{1}}中的新功能而导致错误发生。看起来编译器已经创建了一些AutoLayout个对象,并且由于某种原因,对象的释放超出了应有的范围。删除和重新创建,强制NSLayoutConstraint重建约束。但是,我并非百分百肯定。

尝试 Un-Check "AutoLayout" ,如果它可以解决您的问题。

答案 1 :(得分:0)

你的DetailViewController代码很好 - 实际上并不好,因为你正在泄漏self.replies和self.actions,而[self.docController init]非常奇怪而且可能是错误的(总是一起分配和初始化) - 但是这一端的生命周期代码看起来很好。几乎可以肯定,在父视图控制器中(或者如果您在那里创建保留循环,可能是文档控制器)。如果父视图控制器持有指向详细视图控制器的指针,它实际上不会被释放,并且访问该视图或其任何属性将导致再次调用-viewDidLoad。

答案 2 :(得分:0)

根据我的理解,您的父视图控制器正在此处设置节点:

    dvc.node = selectedReply;

并且它永远不会从您的DetailViewController中释放。

我假设DetailViewController标头中的GDataXMLElement设置为“retain”。

正如icodestuff指出的那样,存在一些泄漏问题。