初始化后直接释放内容视图控制器的弹出框

Posted

技术标签:

【中文标题】初始化后直接释放内容视图控制器的弹出框【英文标题】:Popover deallocating content view controller directly after initialization 【发布时间】:2012-01-30 22:57:22 【问题描述】:

我有一个奇怪的问题,即 UIPopovercontroller 在加载弹出框后立即释放其内容视图控制器,然后重新初始化它。 我的目标是在弹出框被解除时读取文本字段。

我的印象是我创建了一个 UIViewController 并将其设置为弹出框的内容视图控制器。然后 PopoverViewController 将保留内容视图控制器,我可以(自动)释放它。 稍后,当弹出框被解除时,它将释放弹出框(以及内容视图控制器)。但这行不通。这是我的相关代码:

- (IBAction)popoverButton:(id)sender 
  // Create & Initialize content view controller
  ContentViewController* cvc = [[[ContentViewController alloc] initWithNibName:@"ContentViewController" bundle:nil] autorelease];

  // Create, initialize and load popover
  popoverController = [[UIPopoverController alloc] initWithContentViewController:cvc];
  [popoverController setDelegate:self];
  [popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

  NSLog(@"popoverButton: %@, retainCount: %d", cvc, [cvc retainCount]);


- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)senderPopoverController

  NSLog(@"popover should dismiss");
  ContentViewController *dvc = (ContentViewController *)([popoverController contentViewController]);
  NSLog(@"%@ %@ %@", dvc, [dvc testTextfield], [[[dvc testTextfield] text] description]);
  return YES;

ContentViewController.m

- (void)viewDidLoad

  [super viewDidLoad];
  [[self testTextfield] setText:@"Bla"];
  NSLog(@"viewDidLoad: %@", testTextfield);


- (void)dealloc 
  NSLog(@"dealloc: %@", testTextfield);
  [testTextfield release];
  [super dealloc];

当我打开popover时,Log会是(我认为输出的顺序并不代表实际调用时的顺序):

Popover Test[2363:707] viewDidLoad: <UITextField: 0x185750; ...>
Popover Test[2363:707] viewDidLoad: (null)
Popover Test[2363:707] popoverButton: <ContentViewController: 0x1844e0>, retainCount: 4
Popover Test[2363:707] dealloc: <UITextField: 0x185750; ...>

当我关闭它时:

Popover Test[2363:707] popover should dismiss
Popover Test[2363:707] <ContentViewController: 0x1844e0> (null) (null)
Popover Test[2363:707] popover did dismiss
Popover Test[2363:707] <UIPopoverController: 0x184860>
Popover Test[2363:707] dealloc: (null)

所以我的问题是:

    为什么 ContentViewController 再次被释放和初始化? 为什么插座 (textField) 在第二次加载时不再工作?

如果我能解决这个问题,我就能从 popoverControllershouldDismissPopover

中的 textField 读取

【问题讨论】:

【参考方案1】:

由于ContentViewController 是您的类,请实现适当的init* 方法(如果您还没有),设置一个断点,调试器将在每次分配时停止它,回答您的问题,为什么它是正在重新创建。

注意retainCount是没用的;不要叫它。


啊——好的——所以,当您加载 nib 文件时,您正在创建一个实例,并直接在您的代码中创建第二个实例。相反,您需要一个连接到 nib 文件中的实例的插座。

关于retainCount; Calling -retainCount Considered Harmful 和 When to use -retainCount?

【讨论】:

感谢您的回复。我已经为所有的 init 方法实现了跟踪,实际上它只是初始化了一次。 initWithNibName 调用 initWithCoder。就是这样,然后就被deallocated了,我还是不知道为什么。我只是想用retainCount来追踪,不靠谱? 我不确定我是否正确理解了您的答案。我的 ContentViewController 存储在一个单独的 nib 文件中。第一次加载是当我调用 initWithNibFile: 还是我错了?那第二次是什么时候? 抱歉——我想我可能误读了您的评论。你确定它被初始化了两次吗? 我不完全确定,我所拥有的只是我在上面发布的日志,看起来它被释放然后再次初始化。但是,当查看初始化程序时,它们似乎只被调用了一次。但是,在上面的日志中,哪个实例第二次被释放呢?在 Java 中,我会调试整个东西,包括 SDK 以查看发生了什么,但我不能用 ios 来做到这一点:-/ 我想做的就是从 nib 文件加载一个非常简单的弹出窗口,显示它,以及它何时存在解雇,阅读其中的文本字段。非常感谢您的帮助!

以上是关于初始化后直接释放内容视图控制器的弹出框的主要内容,如果未能解决你的问题,请参考以下文章

iOS 弹出框在关闭后不会消失

隐藏弹出框控制器

iPhone的弹出框控制器[关闭]

如何关闭 iPhone 5 iOS 6 中的弹出框?

试图关闭故事板呈现的弹出框

java swing Jpanel 怎么添加一个Jdialog弹出框