为什么在实例化后立即调用dealloc?

时间:2013-10-12 14:41:31

标签: ios objective-c arrays uiviewcontroller dealloc

我在ARC中有一个小问题,并且在循环内实例化后调用了BaseViewController类的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];
  }

}

2 个答案:

答案 0 :(得分:4)

您通过保持对视图控制器视图的引用而不是视图控制器本身来提交常见的初学者错误。

在局部变量categoryView中创建BaseViewController对象。这是一个强大的参考,所以对象保持不变。然后循环重复,并创建一个新的BaseViewController,替换categoryView中的旧值。当你这样做时,不再有对类视图中的前一个BaseViewController的强引用,所以它被取消分配。

如果你想要坚持使用BaseViewController,你需要在某处保留一个强引用。

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

在屏幕上混合来自多个视图控制器的视图将导致您无法解决问题。为了使其发挥作用,您需要做大量的家务管理,而且并非记录所有的内务管理。它的可能,但如果你能做到的话,你需要花费数周的时间来解决这些问题。此外,由于您正在做一些Apple明确表示不会做的事情,因此您需要承担正确的工作负担,并且新的iOS版本可能会破坏您的应用程序。

答案 1 :(得分:0)

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