【问题标题】:UIViewController is correctly dealloced but its UIView is not?UIViewController 已正确释放,但其 UIView 未正确释放?
【发布时间】:2011-05-07 13:02:13
【问题描述】:

我在使用 Apple 的 Instruments “分配”工具时注意到,当我在两个视图之间来回切换时,分配总是会增长。经过调查,我发现所有内存都来自我的 UIViewController 的 UIView 的子视图的对象。

我检查了,我的 UIViewController 正在被释放,但显然 UIView 不是?我没有将 UIView 与 UIView 控制器分开保留。有人有什么想法吗?

这是我编写的用于在视图之间切换的代码。

UISubViewController *viewController = [UIViewControllerFactory createViewController:viewControllerID];     // Creates and returns a UIViewController by ID

[currentViewController viewWillDisappear:YES];
[currentViewController.view removeFromSuperview];
[currentViewController viewDidDisappear:YES];

[viewController viewWillAppear:YES];
[self.view insertSubview:viewController.view atIndex:0];
[viewController viewDidAppear:YES];

self.currentViewController = viewController;
[viewController release];

编辑:
好的,因为担心我只是使用 ViewController 的 View 然后释放 ViewController,所以我尝试了一个实验,我在 NIB 中创建了一个新类,它是文件的所有者,但继承自 NSObject。

现在的代码如下所示:

MyView *myView = [[MyView alloc] initWithNibName:@"myView"];

[currentView viewWillDisappear:YES];
[currentView.view removeFromSuperview];
[currentView viewDidDisappear:YES];

[myView viewWillAppear:YES];
[self.view insertSubview:myView.view atIndex:0];
[myView viewDidAppear:YES];

self.currentView = myView;
[myView release];

MyView 的初始化程序如下所示:

@interface MyView : NSObject {
    IBOutlet UIView *view;
    NSArray *nibTopLevelObjects;
}

@property (nonatomic, retain) UIView *view;

- (id)initWithNibName:(NSString *)nibName;

@end


@implementation MyView

@synthesize view;

- (id)initWithNibName:(NSString *)nibName {
    if (self = [super init]) {

        nibTopLevelObjects = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil];
        [nibTopLevelObjects retain];
    }
    return self;
}

- (void)dealloc {
    [view release];
    [nibTopLevelObjects release];

    view = nil;
    nibTopLevelObjects = nil;

    [super dealloc];
}

@end

每次我换入和换出新视图时,我仍然看到视图的内存泄漏。

有什么新想法吗?

【问题讨论】:

  • 什么是 UIViewControllerFactory,它是如何创建视图的?来自 nib 文件?
  • 是的,UIViewControllerFactory 只是将 viewControllerID 映射到 initWithNibName 的正确字符串,然后返回 viewController。

标签: ios objective-c memory uiviewcontroller abandoned-memory


【解决方案1】:

您的工厂返回一个 viewController,但您只是添加一个视图,而不是推送一个新控制器。在这种情况下,为什么不直接创建一个视图?

您正在做的是不断覆盖 self.currentViewController ivar 而不释放它。您可能正在释放该视图控制器拥有的视图,但仅此而已。

currentViewController 是否定义为

@property (nonatomic, retain) UISubViewController* currentViewController;

也许?如果是这样,则存在与发布不匹配的保留 - 您永远不会在覆盖之前释放 self.currentViewController。如果您不使用self.,即使属性如此定义,它也不会保留。

【讨论】:

  • 其实在使用self的时候。您正在访问该属性,而不是 ivar。 '@property (retain) ...' 的合成版本将在每次使用 self 设置时在保留新 ivar 之前释放旧 ivar。符号。
  • Adam,你是对的,这就是我定义 currentViewController 的方式,但正如你在我的 sn-p 中看到的那样,我确实调用了 self.currentViewController,它在分配新的 ViewController 之前正确地释放了旧的 ViewController。
  • 你和 Dean 询问了我添加视图的问题。有没有更好的方法来显示 ViewController 的视图?
【解决方案2】:

您正确地删除了旧视图并添加了一个新视图。这意味着您在 SubViewController 中的某个地方错误地保留了视图,或者您正在模拟器而不是设备中进行测试。

您能否发布您的 SubViewController 代码以查看其中发生了什么?

当您在真实设备上进行测试时,您会得到相同的结果吗?


PS Adam Eberbach 提出了一个公平的观点 - 你为什么要创建一个视图控制器只是为了窃取它的视图然后释放它?

【讨论】:

  • 我会在这里回答亚当的问题,因为我在完成之前不小心在下面发布了。 ViewController 不会消失,它通过调用 self.currentViewController 被保留。我将视图的所有逻辑封装在其 ViewController 中。所以我有一个标准的方式来响应 viewDidLoad、viewWillAppear、didReceiveMemoryWarning 等。
  • 我在模拟器中运行它。我不应该吗?当我在设备上运行时,我确实看到了相同的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-24
  • 2014-12-17
  • 2018-08-27
  • 2011-06-08
  • 2011-06-01
  • 2011-09-09
  • 2010-12-30
相关资源
最近更新 更多