2

我在循环内实例化后调用 BaseViewController 类的 ARC 和 dealloc 有一个小问题,我不知道为什么。我要做的基本上是将所有基本视图控制器存储在一个数组上。

@interface CategoriesContainerViewController ()
  @property (nonatomic, strong) IBOutlet UIScrollView* scrollView;
  @property (nonatomic, strong) NSMutableArray* categoriesViews;
@end

- (void)viewDidLoad {

  [super viewDidLoad];

  // Get the categories from a plist
  NSString* path = [[NSBundle mainBundle] pathForResource:@"categories" ofType:@"plist"];
  NSDictionary* dict = [[NSDictionary alloc] initWithContentsOfFile:path];
  NSMutableArray* categories = [dict objectForKey:@"Categories"];
  NSLog(@"%i", [categories count]);

  // Setup the scrollview
  _scrollView.delegate = self;
  _scrollView.directionalLockEnabled = YES;
  _scrollView.alwaysBounceVertical = YES;
  _scrollView.scrollEnabled = YES;

  CGRect screenRect = [[UIScreen mainScreen] bounds];

  // Loop through the categories and create a BaseViewController for each one and
  // store it in an array
  for (int i = 0; i < [categories count]; i++) {

    BaseViewController* categoryView = [[BaseViewController alloc]
                                        initWithCategory:[categories objectAtIndex:i]];

    CGRect frame = categoryView.view.frame;
    frame.origin.y = screenRect.size.height * i;
    categoryView.view.frame = frame;

    [_scrollView addSubview:categoryView.view];
    [_categoriesViews addObject:categoryView];
  }

}
4

2 回答 2

4

通过保留对视图控制器视图的引用,而不是视图控制器本身,您犯了一个常见的初学者错误。

您在局部变量 categoryView 中创建一个 BaseViewController 对象。这是一个强引用,所以对象被保留。然后循环重复,您创建一个新的 BaseViewController,替换 categoryView 中的旧值。当您这样做时,不再有对 categoryView 中以前的 BaseViewController 的任何强引用,因此它被释放。

如果您希望 BaseViewController 继续存在,您需要在某处保留对它的强引用。

除此之外,您还打破了 iOS 开发的另一条规则。除非您使用在 iOS 5 中添加并在 iOS 6 中扩展的父/子视图控制器支持,否则您永远不应该将一个视图控制器的视图放在另一个视图控制器中。文档说不要这样做。

在屏幕上混合来自多个视图控制器的视图会给你带来无穷无尽的问题。为了使其正常工作,您必须进行大量的内务处理,而且并非所有的内务处理都被记录在案。有可能,但如果可以的话,您将花费数周时间来消除这些错误。另外,由于您正在做 Apple 明确表示不做的事情,因此您有责任使其正常工作,并且新的 iOS 版本会破坏您的应用程序的风险很大。

于 2013-10-12T15:14:24.743 回答
0

上面的 for 循环初始化 BaseViewController,然后将数组值存储在 BaseViewController 的对象中。因为每次它都在分配和初始化。所以将前一个对象设置为零。因此,该问题导致被解除分配。

于 2013-10-12T15:23:29.963 回答