UIVIew 子类对象在标签栏应用程序中变得神秘 [英] UIVIew subclass object becomes mysteriously nil in tabbar app

查看:31
本文介绍了UIVIew 子类对象在标签栏应用程序中变得神秘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Hola caballeros,我被难住了,迷惑了,更糟糕的是,在我的第一个标签栏项目中,我有一个对象,它是一个子类UIView 的 BarGraph"的实例,我以前使用过没有问题.在这个项目我在第二个 viewController 的 viewDidLoad 方法中执行 alloc-init,graphViewController.这设置了 BarGraph.读入的数据由该对象正确显示.

Hola caballeros, I am stumped, mystified, and worse yet, stymied: in my first tab bar project I have an object that is instance of a subclass "BarGraph of UIView, which I've used before without trouble. In this project I do an alloc-init in the viewDidLoad method of the second viewController, graphViewController. This sets up the BarGraph. The data which is read in is displayed properly by that object.

当我使用选项卡转到我添加到数据的不同 viewControler 时,问题就来了.我看到了适当的可变数组的变化.一个OK.但是当我回到另一个选项卡时,BarGraph 显示的数据和以前一样.经过一番检查,我发现 BarGraph 对象变成了 NULL:

The trouble comes when I use a tab to go to a different viewControler where I add to the data. I see the change in the appropriate mutable array. AOK. But when I come back to the other tab, the data displayed by BarGraph is the same as before. After some checking, I found that the BarGraph object had become NULL:

NSLog(@"barGraph:%@", barGraph) 

给出空".我所有的修复尝试都失败了.我只看到这个对象的一个​​ alloc-init 而没有 deallocs.这些是我用 NSLog 跟踪的.太奇怪了.我等待你的建议.

gives "null". All my attempts to fix fail. I see only one alloc-init for this object and no deallocs. These I tracked with NSLog's. Too weird. I await your advice.

编辑添加

这是我的界面:

@interface GraphViewController : UIViewController { 
BarGraph *barGraph; 
int foo; 
} 

@property (nonatomic, retain) BarGraph *barGraph; 
@property (assign) int foo; 

- (void) updateDisplay; 

@end

* 来自 epsilon2.7 aka Jim Carlson:* 下面是我在 GraphViewController.m 中实例化 BarGraph 的地方.我添加了一行foo = 100;"查看问题是否与所有 ivars 或仅与 barGraph 有关.唉, foo 和 barGraph 在跳开然后跳回时忘记"了它们的值.我非常感谢反馈(以及对新手的善意).

* from epsilon2.7 aka Jim Carlson: * Below is where I instantiate BarGraph in GraphViewController.m. I added one line "foo = 100;" to see if the problem has to do with all ivars or just barGraph. Alas, both foo and barGraph "forget" their values when tabbing away and then tabbing back. I very much appreciate the feedback (and the kindness to a newb).

@implementation GraphViewController

@synthesize barGraph, foo;

- (XTabAppDelegate *) theDelegate {
    return (XTabAppDelegate *) [UIApplication sharedApplication].delegate;
}

....

- (void)viewDidLoad {
[super viewDidLoad];
    NSLog(@"BARGRAPH: alloc-init");
    barGraph = [[BarGraph alloc] initWithFrame:CGRectMake(15, 118, 289, 110)];
    foo = 100;
    [self.view addSubview:barGraph];
    [self updateDisplay];
}

....

@end

应用程序委托的接口,其中存储了图形化的数据:

Interface for app delegate, where the data graphed is stored:

    @interface XTabAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {

UIWindow *window;
UITabBarController *tabBarController;

    LogViewController *logViewController; // good
    GraphViewController *graphViewController; // bad

    Log *currentLog; // data stored here
}

...
@end

currentLog 中的数据仍然存在(NSLog 在 GraphViewController 中确认了这一点),我在 GraphViewController 中使用以下代码将该数据推送到 barGraph:

The data in currentLog persists (NSLog confirms this in GraphViewController), and I push that data into barGraph with the following code in GraphViewController:

    -(void) updateBarGraphForDay { 
        Log *theLog = [self theDelegate].currentLog;
        barGraph.data = theLog.log;  // main data stored in the theLog.log
        foo += 1;
}

根据 ughoavgfhw 的评论,我检查了 graphViewController 和 BarGraph 的 dealloc,例如通过插入 NSLog 语句:

Following up ughoavgfhw's comment, I checked dealloc for both graphViewController and BarGraph, e.g. by inserting an NSLog statement:

- (void)dealloc {
    NSLog(@"deallocating GraphViewController");
    [barGraph dealloc];
    [super dealloc];
}

两者都不叫!

我从来没有看到过dealloc.

I never see the dealloc.

(2) 下面是didSelectViewController的代码.随着

(2) Below is the code for didSelectViewController. With

xtabBarController.delegate = self; 

在委托的didFinishLaunchingWithOptions 方法主体的第一行,方法didSelectViewController(下面的代码)被执行.如果 [graphViewController updateDisplay] 没有被注释掉,那么 (a) 我检测到一个 nil barGraph 对象,(b) 我没有看到显示的新数据(可能是因为相关消息转到了一个 nil 对象), (c) 如果我通过按下按钮在 graphViewController 中手动执行 [graphViewController updateDisplay] ,则显示更新的信息.

in place as the first line of the body of the delegate's didFinishLaunchingWithOptions method, the method didSelectViewController (code below) is executed. If [graphViewController updateDisplay] is not commented out, then (a) I detect a nil barGraph object, (b) I do not see the new data displayed (probably since the relevant message went to a nil object), (c) if I execute [graphViewController updateDisplay] manually in graphViewController by pushing a button, then the updated info is displayed.

// Optional UITabBarControllerDelegate method.
- (void)tabBarController:(UITabBarController *)tabBarController      didSelectViewController:(UIViewController *)viewController {
    NSLog(@"UITabBarControllerDelegate method called");
    if (viewController == [tabBarController.viewControllers objectAtIndex:1]) {
        NSLog(@"graphViewController selected, graphViewControler = %@", graphViewController);
        [graphViewController updateDisplay];
    }
    ... + similar if statements
}

可能是 [graphViewController updateDisplay] 调用过早,graphViewController 未初始化 (???).我试图通过在 graphViewController 中实现 viewWillAppear 来规避这些困难.但是,NSLog 告诉我 viewWillAppear 永远不会被调用.下面是 viewWillAppear 的代码:

It may be that [graphViewController updateDisplay] is called too early, when graphViewController is not initialized (???). I've tried to circumvent these difficulties by implementing viewWillAppear in graphViewController. However, NSLog informs me that viewWillAppear is never called. Here is the code for viewWillAppear:

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:TRUE];
    NSLog(@"bb:graphViewController, viewWillAppear called");
    [self updateDisplay];
}

推荐答案

您的问题是当您更改选项卡时 GraphViewController 正在被释放和重新加载.当一个视图控制器不被使用时,它被释放.然后,当再次需要它时,就会创建一个新的.任何持久信息都应存储在控制器对象访问的模型对象中.这是基本的模型-视图-控制器编程.创建 GraphViewController 后,它应该连接到模型对象并从中加载其信息,而不是尝试自行存储.

Your problem is that the GraphViewController is being released and reloaded when you change tabs. When a view controller is not being used, it is released. Then, when it is needed again, a new one is created. Any persistent information should be stored in a model object which is accessed by the controller object. This is basic model-view-controller programming. When your GraphViewController is created, it should connect to a model object and load its information from that, instead of trying to store it itself.

这篇关于UIVIew 子类对象在标签栏应用程序中变得神秘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆