【问题标题】:makeKeyAndOrderFront barfs on second use... (ARC?)makeKeyAndOrderFront 在第二次使用时吐槽……(ARC?)
【发布时间】:2015-04-27 00:41:54
【问题描述】:

问题...

我之前使用 MainMenu.xib 中的这段代码来管理窗口:

--

if([olt_MainMenu_WINDOW isVisible]){
    [olt_MainMenu_WINDOW setReleasedWhenClosed:NO];
    [olt_MainMenu_WINDOW close];
}

...然后

if(olt_DoSomething_WINDOW == nil)
    if(![[NSBundle mainBundle] loadNibNamed:@"DoSomething" owner:self topLevelObjects:nil])
        NSBeep();
if(olt_DoSomething_WINDOW != nil)
    [olt_DoSomething_WINDOW makeKeyAndOrderFront:nil];

--

...然后回到我的 MainMenu.xib 中的窗口:

--

if([olt_DoSomething_WINDOW isVisible]){
    [olt_DoSomething_WINDOW setReleasedWhenClosed:NO];
    [olt_DoSomething_WINDOW close];
}

...然后

if(olt_MainMenu_WINDOW == nil)
    if(![[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:self topLevelObjects:nil])
        NSBeep();
if(olt_MainMenu_WINDOW != nil)
    [olt_MainMenu_WINDOW makeKeyAndOrderFront:nil];

--

但如果我再次尝试在 DoSomething 窗口中设置 KeyAndOrderFront,则会出现 exc_bad_access (code=1 ...

我可以多次将 MainMenu 设为 KeyAndOrderFront,但其他任何一次都不能。我错过了什么?

是的,在窗口的属性检查器中未选择“关闭时释放”。这是我第一次在 ARC 中使用它,可能与此有关吗?

【问题讨论】:

  • 运行分析器。有什么警告吗?修复它们。然后在启用僵尸的情况下运行。任何僵尸错误?修复它们,或编辑您的问题以包含错误。 (有关启用僵尸的方法,请参阅 thisthis。)
  • 我认为这个 SO 问题可能会对您有所帮助:stackoverflow.com/questions/1221516/…
  • 分析器没有返回任何警告,但我受到了僵尸的打击:'2015-04-27 14:06:22.730 Six[4660:97785] *** -[DoSomething windowDidBecomeKey:]: message sent到释放的实例 0x6080000a5a60 (lldb)'
  • Henrietta,请截取 Instruments 中窗口的保留/释放历史记录并发布。
  • 你在哪里以及如何存储 DoSomething 窗口(控制器)ptr?

标签: objective-c macos cocoa


【解决方案1】:

基于reference for loadNibNamed:owner:topLevelObjects:,我猜你有一个弱IBOutlet 到doSomething 笔尖中的NSWindow 顶级对象。由于您没有传递 &myArray 之类的内容,而是使用 topLevelObjects:nil,因此很明显“有必要通过使用 IBOutlets 来保持对它们的强引用。”

讨论

与传统方法不同,对象 [topLevelObjects-ed.] 遵循标准可可内存管理规则;有必要通过使用 IBOutlets 或持有对数组的引用来保持对它们的强引用,以防止 nib 内容被释放。

顶级对象的出口应该是强引用,以证明所有权并防止重新分配。

你需要:

@property (strong) IBOutlet NSWindow *olt_DoSomething_WINDOW;

... 或以其他方式保持对窗口的强引用。 IBOutlets 通常很弱,因为它们是由其父视图保留的视图元素,您不需要控制器保留,但您的 NSWindow 没有保留所有者,除非您明确创建一个。因此,您实际上需要一个强大的 IBOutlet。

【讨论】:

  • 谢谢史蒂夫、克里斯和罗布。 @property (strong) IBOutlet NSWindow *olt_DoSomething_WINDOW;作品。此外,要更新代码以使其如上(几年前)发布的那样工作,我需要将“setReleasedWhenClosed”更改为“orderOut”。 :)
  • 顺便说一句,strong 在没有指定其他内容时是隐含的,但在这种情况下最好是明确的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-01
  • 2018-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多