【发布时间】:2011-01-29 16:11:14
【问题描述】:
我一直在开发一个标签栏应用程序,它有一个让我难过的错误(仍然)。
当我进入一个新选项卡时,存储在应用程序模型部分中的数据不会被视图使用,因此会显示陈旧的信息(图表、数字等)。我尝试了两种强制更新的方法,由[self updateDisplay] 在视图中处理。 (1)在app delegate中,使用UITabBarControllerDelegate方法判断选择了哪个tab,然后给它发送更新消息。这是委托方法的一部分:
if (viewController == [tabBarController.viewControllers objectAtIndex:1]) {
NSLog(@"graphViewController selected, graphViewController = %@", graphViewController);
[graphViewController updateDisplay];
}
这是我想做的工作的方式。然而,显示并没有更新,尽管 NSLog 确认 updateDisplay 已经触发。
(2) 通过执行[self updateDisplay],在视图中按下按钮以更新显示。这有效,但并不令人满意。有趣的来了。在下面的日志中,我们看到(1)委托方法被调用,(2)graphViewController被选中,(3)graphViewController的updateDisplay方法被调用。伟大的!但是此时barGraph 为空,并且包含从ourLog 中的浮点数读取的标签的显示不会更新。对象ourLog 是模型的一部分,它与“磁盘”上的文件同步。 (barGraph 更新自 ourLog 至 updateDisplay)。
继续前进,我们现在在由 GraphViewController 管理的视图中,我们按下“测试”按钮 (6),updateDisplay 被调用,视图正确更新。
请注意,在 1--5 中,GraphViewController 位于 0x4e346e0,而在 6--9 中,它位于 0x4b53c80。如果你来回切换,切换和切换,按下“测试”按钮,你总是会得到十六进制数字。起初我认为不知何故有两个GraphViewController 的实例漂浮在周围。但是我覆盖了该类的 init 方法以便记录它。它只出现一次。所以我完全被难住了。
-- 吉姆
- 1] 调用 UITabBarControllerDelegate 方法,self =
- 2] 选择graphViewController,graphViewController =
- 3] GraphViewController,updateDisplay 调用,self =
- 4] 我们的日志:
- 5] updateDisplay, barGraph: (null)
- 6] 测试推送
- 7] GraphViewController,updateDisplay 调用,self =
- 8] 我们的日志:
- 9] 更新显示,条形图:>
PS。我最初在UIVIew subclass object becomes mysteriously nil in tabbar app 发布了这个。我重新发布这个问题是因为问题更普遍,barGraph 在应用程序生命周期的各个阶段为空。不知何故,当我调用它时需要访问的东西不是,所以我必须找出一种不同的方式来调用它。但它并没有消失(我也覆盖了dealloc,并没有发现barGraph 曾经发布过)。
附录 1:条形图。
这是在 GraphViewController 中创建 barGraph 的方式:
@interface GraphViewController : UIViewController {
BarGraph *barGraph;
}
@property (nonatomic, retain) BarGraph *barGraph;
@property (nonatomic, retain) IBOutlet UIButton *testButton;
- (void) updateDisplay;
- (IBAction) testAction: (id) sender;
@end
在@implementation,viewDidLoad alloc-inits barGraph:
- (void) viewDidLoad {
[super viewDidLoad];
NSLog(@"xx:BARGRAPH: alloc-init in viewDidLoad, GraphBar");
barGraph = [[BarGraph alloc] initWithFrame:CGRectMake(15, 140, 289, 130)];
[self.view addSubview:barGraph];
[self updateDisplay];
}
最后,这里是updateDisplay的实现:
- (void) updateDisplay {
// Check to see where GraphViewController is:
NSLog(@"GraphViewController, updateDisplay called, self = %@", self);
// Get a pointer to the current data to graph
Log *ourLog = [self theDelegate].currentLog
// Log info
NSLog(@"ourLog: %@", ourLog);
NSLog(@"updateDisplay, barGraph: %@", self.barGraph);
// Get the current data out of ourLOg
self.barGraph.data = ourLog.log;
// And ask barGraph to display it
[barGraph setNeedsDisplay];
}
附录 2:viewWillAppear。
我将viewWillAppear添加到GraphViewController.m如下:
- (void) viewWillAppear:(BOOL)animated
{
NSLog(@"xx: GraphViewController, viewWillAppear has fired");
[super viewWillAppear:animated];
[self updateDisplay];
}
这似乎是正常和最佳的解决方案,但 viewWillAppear 永远不会触发。注意方法testAction,通过按钮激活:
- (IBAction) testAction: (id) sender {
NSLog(@"test pushed");
[self updateDisplay];
}
按下已连接的按钮以正确更新显示。但我当然希望 iOS 按下按钮,而不是我:-)
【问题讨论】:
标签: iphone cocoa-touch uiviewcontroller uitabbarcontroller