0

我制作了一个自定义容器控制器,其中包括在两个控制器之间切换。当我将第一个控制器的视图添加到我的容器控制器时,Instrument 显示内存泄漏。我目前有以下实现:

。H

#import <UIKit/UIKit.h>

@interface SCLDefaultSwitchViewController : UIViewController
{
@protected
    __weak UIViewController *_activeController;
}

@property (nonatomic, weak, readonly) UIViewController *activeController;
@property (nonatomic, weak) UIViewController *leftViewController;
@property (nonatomic, weak) UIViewController *rightViewController;

@结尾

米:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // set-up content container view
    self.view.autoresizesSubviews = YES;

    [self performSegueWithIdentifier:@"left" sender:self];
    NSAssert( (_leftViewController != nil) , @"left view controller shouldn't be nil!");
    _activeController = _leftViewController;

    [self addChildViewController:_activeController];
    [self.view addSubview:_activeController.view];   // ---> memory leak here!!!!!
    [_activeController didMoveToParentViewController:self];

    [self performSegueWithIdentifier:@"right" sender:self];
    NSAssert( (_rightViewController != nil) , @"right view controller shouldn't be nil!");
    [self addChildViewController:_rightViewController];
    [_rightViewController didMoveToParentViewController:self];

    //[self performSelectorInBackground:@selector(performBackgroundTasks) withObject:nil];
}

我确保在两个视图之间切换时视图已从其父视图中正确删除:

- (void) didTapOnStartButton:(SCLSplashScreenViewController *)sender
{
    //CGRect originFrame   = _contentContainerView.bounds;
    CGRect originFrame   = self.view.bounds;
    CGRect offsetFrame   = originFrame;
    offsetFrame.origin.x =  originFrame.size.width;

    UIViewController* toViewController   = self.rightViewController;
    UIViewController* fromViewController = self.leftViewController;

    toViewController.view.frame = offsetFrame;

    __weak SCLSwitchViewController *weakSelf = self;
    [self transitionFromViewController:fromViewController
                      toViewController:toViewController
                              duration:.4f
                               options: UIViewAnimationOptionCurveEaseOut
                            animations:^{
                                weakSelf.rightViewController.view.frame = originFrame;
                            }

                            // remove the splash screen controller when the animation is finished and delete it: we don't need it anymore
                            completion:^(BOOL finished){
                                if (finished){
                                    [weakSelf.leftViewController willMoveToParentViewController:nil];
                                    [weakSelf.leftViewController.view removeFromSuperview];
                                    [weakSelf.leftViewController removeFromParentViewController];
                                    weakSelf.leftViewController = nil;
                                    weakSelf.activeController = toViewController;
                                }
                            }];
}

我真的看不出它应该泄漏的任何充分理由:有什么想法吗?

4

2 回答 2

0

要确定您的代码发生了什么,我们需要查看 View Propery 中的确切内容。但不是来自您的弱参考,而是来自您的 _leftViewController。由于它是活动控制器并且它是您添加的第一个控制器,因此它在该实际类中,而不仅仅是添加该视图。

[self performSegueWithIdentifier:@"left" sender:self];
NSAssert( (_leftViewController != nil) , @"left view controller shouldn't be nil!");
_activeController = _leftViewController; /**Check Inside _leftViewController. **/

[self addChildViewController:_activeController];
[self.view addSubview:_activeController.view];   // ---> memory leak here!!!!! 

我们需要查看您的代码 INSIDE _leftViewController 以确定发生了什么。您添加的哪些子视图在 dealloc 时没有被删除。即使启用了 ARC,但有时在循环中,某些对象会停留更长时间并造成一些内存泄漏。所以使用

@autorealease {}

自动释放片段可以帮助解决这些情况。

但是就像我说的那样,我们需要该代码来确定您的代码到底发生了什么。但我敢打赌,问题就在那里。(根据你提供给我们的证据)。

于 2013-10-12T15:03:40.353 回答
0

为什么要再次添加新的 viewController?如果在 Storyboard 中使用正确的标识符设置了 segue,那么您不需要手动添加 childViewControllers。把这个留给segue。尝试将您的代码更改为:

- (void)viewDidLoad
{
[super viewDidLoad];

// set-up content container view
self.view.autoresizesSubviews = YES;

[self performSegueWithIdentifier:@"left" sender:self];

[self performSegueWithIdentifier:@"right" sender:self];

//[self performSelectorInBackground:@selector(performBackgroundTasks) withObject:nil];
}

然后在“prepareForSegue:”中将 Active VC 设置为 LeftVC,不使用全局对象,而是使用 segue 本身的“destinationViewController”。也就是说,你为什么这样做有点令人困惑,所以关于你想要达到的目标的更多信息会有所帮助。

麦克风。

于 2013-10-12T10:31:42.620 回答