添加到滚动视图后,完全加载的 UIViewController 丢失所有数据
摘要
我正在重新利用 Apple 的页面控制项目。在 loadScrollViewWithPage: 中,我添加到滚动视图的视图控制器出现在屏幕上,但没有初始化值,就像直接从笔尖显示一样。
具体
这是当我单步执行时似乎正在工作的代码:
CBFullScreenViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null]) {
controller = [[CBFullScreenViewController alloc] init];
// Populate the view from the corresponding CBImage object
CBImage *imageObject = [imageArray objectAtIndex:page];
BOOL bookmarked = [imageObject.bookmarked boolValue];
controller.bookmarkButton.highlighted = bookmarked;
NSString *subtitle = imageObject.subtitle;
controller.closedSubtitleLabel.text = subtitle;
// <-- snip...more initialization --> //
controller.delegate = self;
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
// 将控制器的视图添加到滚动视图 if (nil ==controller.view.superview) { CGRect框架=scrollView.frame; frame.origin.x =frame.size.width * 页; 框架.origin.y = 0; 控制器.view.frame = 框架; [scrollView addSubview:controller.view];//<<控制器和子视图 } // 看起来都是非空的 // 此时的有效值
这是 CBFullScreenViewController 中的 init 方法:
- (id)init {
if ((self = [super initWithNibName:@"CBFullScreenViewController" bundle:nil])) {
self.cover = [[UIImageView alloc] init];
self.homeButton = [[UIButton alloc] init];
self.tabView = [[UIButton alloc] init];
self.closedSubtitleLabel = [[UILabel alloc] init];
self.openSubtitleLabel = [[UILabel alloc] init];
// <-- snip...more initialization --> //
}
return self;
}
虽然过去 2 小时的故障排除帮助我追踪了一些不相关的内存泄漏,但我一生都无法弄清楚我的值发生了什么'我进入我的视野!
哦,也许值得一提的是,我的每个网点都有@synthesize,而且它们都与 IB 挂钩。屏幕截图此处。
Summary
I'm repurposing Apple's Page Control project. In loadScrollViewWithPage:, the view controllers that I'm adding to the scroll view appear on screen without their initialized values, as if displayed directly from the nib.
Specifics
Here's the code that appears to be working when I step through it:
CBFullScreenViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null]) {
controller = [[CBFullScreenViewController alloc] init];
// Populate the view from the corresponding CBImage object
CBImage *imageObject = [imageArray objectAtIndex:page];
BOOL bookmarked = [imageObject.bookmarked boolValue];
controller.bookmarkButton.highlighted = bookmarked;
NSString *subtitle = imageObject.subtitle;
controller.closedSubtitleLabel.text = subtitle;
// <-- snip...more initialization --> //
controller.delegate = self;
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
// add the controller's view to the scroll view
if (nil == controller.view.superview) {
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];//<< controller and subviews
} // all have non-null, seemingly
// valid values at this point
Here's the init method in CBFullScreenViewController:
- (id)init {
if ((self = [super initWithNibName:@"CBFullScreenViewController" bundle:nil])) {
self.cover = [[UIImageView alloc] init];
self.homeButton = [[UIButton alloc] init];
self.tabView = [[UIButton alloc] init];
self.closedSubtitleLabel = [[UILabel alloc] init];
self.openSubtitleLabel = [[UILabel alloc] init];
// <-- snip...more initialization --> //
}
return self;
}
While troubleshooting this for the last 2 hours has helped me track down some unrelated memory leaks, I can't for the life of me figure out what's happening to the values I'm putting into my view!
Oh, it's probably worth mentioning that I've got @synthesize for each of my outlets, and they're all hooked up in IB. Screenshot here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
几个小时后......
我的解决方案
如上所述,我终于找到了一条线索,直到我完成了按钮上的所有初始化之后,子视图的 viewDidLoad 才会触发等等,这意味着笔尖覆盖了我所有的初始化。
一种有效的解决方案是使滚动视图成为子视图的委托...
然后通过从子视图的 viewDidLoad 中调用委托中的函数来初始化所有内容。
CBFullScreenViewController.h
CBScrollViewController.m
更好的解决方案
但最终,问题是架构上的。我实现它的第一种方法是,当每个视图都滑动到位时,我的所有控件都会被复制,这既丑陋又浪费。
上面的代码显示了我的子视图中除了 UIImageView 之外什么都没有,因为所有控件实际上只需要加载一次:在图像上一动不动地浮动。为单个全屏视图加载笔尖完全是多余的。
那么,更好的解决方案是使用 Interface Builder 来实现滚动视图的更复杂的布局,其中包含我拥有的按钮和滑动信息选项卡,但将 Interface Builder 排除在子视图之外,子视图可以轻松地以编程方式加载。
Hours later....
My solution
As noted above, I finally found a clue in that the sub-views' viewDidLoads weren't firing until after I'd done all my initialization on the buttons and whatnot, implying that the nib was overwriting all of my initialization.
One solution that worked was to make the scroll view a delegate of the subviews...
and then initialize everything by calling a function in the delegate from within the subview's viewDidLoad.
CBFullScreenViewController.h
CBScrollViewController.m
An even better solution
In the end, though, the problem was architectural. The first way I implemented it, all of my controls were duplicated as each view was swiped into place, which was both ugly and wasteful.
The code above shows how I ended up having nothing in my subviews other than a UIImageView because all of the controls really only needed to be loaded once: floating motionless over the image. Loading a nib for a single, full-screen view is total overkill.
The better solution, then, is to use Interface Builder for the scroll view's more complex layout with the buttons and sliding info tab that I had, but leave Interface Builder out of it for the subviews, which can just as easily be loaded programmatically.