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];
}
答案 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时,它应该连接到模型对象并从中加载信息,而不是尝试自己存储它。