1

概括

我正在重新利用 Apple 的Page Control项目。在 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 frame = scrollView.frame; frame.origin.x = frame.size.width * 页;frame.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 挂钩。截图在这里

4

1 回答 1

0

几小时后....

我的解决方案

如上所述,我终于找到了一个线索,即子视图的viewDidLoad直到我对按钮等进行了所有初始化之后才触发,这意味着笔尖正在覆盖我的所有初始化。

一种有效的解决方案是使滚动视图成为子视图的代表......

@interface CBScrollViewController : UIViewController
          <***CBFullScreenViewControllerDelegate***, UIScrollViewDelegate> {
...etc...

然后通过在子视图的 viewDidLoad 中调用委托中的函数来初始化所有内容。

CBFullScreenViewController.h

@protocol CBFullScreenViewControllerDelegate
- (UIImage *)imageForFullScreenView:(CBFullScreenViewController *)controller;
@end

CBScrollViewController.m

- (UIImage *)imageForFullScreenView:(CBFullScreenViewController *)controller {
    NSUInteger page = controller.pageNumber;
    CBImage *image = [imageArray objectAtIndex:page];
    UIImage *pixels = [CBDataAccess pixelsForImage:image];
    return pixels;
}

更好的解决方案

但最终,问题出在架构上。我实现它的第一种方式是,当每个视图都滑动到位时,我的所有控件都被复制了,这既丑陋又浪费。

上面的代码显示了我如何最终在我的子视图中除了 UIImageView 之外什么都没有,因为所有控件实际上只需要加载一次:在图像上一动不动。为单个全屏视图加载笔尖完全是矫枉过正。

那么,更好的解决方案是将 Interface Builder 用于滚动视图的更复杂的布局,其中包含我拥有的按钮和滑动信息选项卡,但将 Interface Builder 保留在子视图之外,它可以很容易地以编程方式加载。

于 2010-05-03T22:18:00.723 回答