在tabbar应用程序中,UIVIew子类对象变得神秘无效

时间:2010-12-16 00:01:44

标签: iphone null uitabbarcontroller

Hola caballeros,我感到困惑,神秘,更糟糕的是,在我的第一个标签栏项目中,我有一个对象是UIView的子类“BarGraph”的实例,我之前使用过它没有任何问题。 project我在第二个viewController的viewDidLoad方法中执行了一个alloc-init,这个方法设置了BarGraph。读入的数据被该对象正确显示。

当我使用标签转到我添加到数据的其他viewControler时出现问题。我看到适当的可变数组的变化。一个OK。但当我回到另一个标签时,BarGraph显示的数据与之前相同。经过一些检查,我发现BarGraph对象变为NULL:

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

给出“null”。我修复的所有尝试都失败了。我看到这个对象只有一个alloc-init而没有deallocs。这些是我跟踪NSLog的。太奇怪了。我在等你的建议。

已编辑添加

这是我的界面:

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

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

- (void) updateDisplay; 

@end

*来自epsilon2.7又名Jim Carlson: * 下面是我在GraphViewController.m中实例化BarGraph的地方。我添加了一行“foo = 100;”看问题是否与所有ivars或barGraph有关。唉,foo和barGraph都会“忘记”他们的价值观,然后立即退出。我非常感谢反馈(以及对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

app delegate的界面,其中存储了绘制的数据:

    @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中:

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

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

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

两者都没有被召唤!

我从未见过dealloc。

(2)以下是didSelectViewController的代码。随着

xtabBarController.delegate = self; 

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

// 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。我试图通过在viewWillAppear中实施graphViewController来规避这些困难。但是,NSLog通知我viewWillAppear永远不会被调用。以下是viewWillAppear的代码:

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

3 个答案:

答案 0 :(得分:0)

不是很多,所以在这里黑暗中拍摄。但是,如果一个对象被释放,那么指向该对象的指针就不会被删除。如果明确设置它们,它们将被排除在外。此外,您看到旧图表的事实向我表明该对象存在于内存中的某些位置。

所以,我猜你将这个指针存储在某个类中,例如A.你有一个由变量x指向的类A的实例。您的barGraph存储在x中。在从一个标签移动到另一个标签的过程中的某个时刻。变量x用新的A实例重新初始化。这个新实例还没有初始化它的barGraph,所以是null。但是,旧的A实例仍然存在于某处,并且仍然保持指向barGraph的指针。

答案 1 :(得分:0)

黑暗中另一个近乎完整的刺:你的BarGraph对象是​​一个综合属性,但在那个viewController中,你不小心引用了iVar(barGraph =)而不是属性(self.barGraph =)所以它在viewController中看起来正确但你正在记录属性,它仍然是零。

答案 2 :(得分:0)

您的问题是,当您更改标签时,GraphViewController正在发布并重新加载。当未使用视图控制器时,它将被释放。然后,当再次需要时,创建一个新的。任何持久性信息都应存储在由控制器对象访问的模型对象中。这是基本的模型 - 视图 - 控制器编程。创建GraphViewController时,它应该连接到模型对象并从中加载信息,而不是尝试自己存储它。