【问题标题】:NSPopover deallocation when losing focus (OSX, Objective-C)失去焦点时的 NSPopover 释放(OSX,Objective-C)
【发布时间】:2017-04-12 06:56:02
【问题描述】:

我使用的是 OSX(不是 iOS),Xcode 8.2,启用了 ARC,Objective-C。

我有一个视图可以在单击按钮时打开一个弹出框。两者都与一个委托和一个协议连接,该协议允许访问以下方法(以及其他方法)

- (id)valueForKey:(NSString*)key;
- (void)setValue:(id)value forKey:(NSString *)key;

(我经常使用这个协议,需要尽可能保持干净和不具体)

在弹出窗口的视图中,有另一个按钮可以打开 NSOpenPanel。一旦面板打开,弹出框就会消失并被释放 - 这是首选行为......通常。不幸的是,我需要 openPanel 通过协议方法保存到父视图。但是如果弹出框被释放,这些方法就不再可用了。

因此,我尝试在 openPanel 之前创建对要保存到的值的强引用,然后将其释放以将 popover viewController 保留在内存中。但是一旦我尝试释放它......它就会崩溃。

@interface SHWildcardItemSettingImageViewController ()

    @property (strong) NSString* customImagePathBookmark;

@end


@implementation SHWildcardItemSettingImageViewController

     // Create strong reference to delegate (to not dealloc popoverViewController)
    [self setCustomImagePathBookmark:[_delegate valueForKey:@"customImagePathBookmark"]];

     // Setup open panel
    NSOpenPanel *openPanel = [[NSOpenPanel alloc] init];
    [openPanel setAllowsMultipleSelection:NO];
    [openPanel setCanChooseDirectories:YES];
    [openPanel setCanChooseFiles:NO];
    [openPanel setCanCreateDirectories:YES];
    [openPanel setPrompt:@"Choose folder"];

    // Display the dialog box.  If the OK pressed, process the folder.
    if ( [openPanel runModal] == NSModalResponseOK ) {

    // Gets list of all files selected
    NSArray *files = [openPanel URLs];

    // Create and save Bookmark for later use (_bookmarks is a custom NSObject)
    [_delegate setValue:[_bookmarks bookmarkFromURL:[files objectAtIndex:0]] forKey:@"customImagePathBookmark"];
}

    [self setCustomImagePathBookmark:nil]; // <---- Crashes here
@end

在不使用不同的 NSPopoverBehaviours 的情况下,在 NSOpenPanel 处于焦点时保持弹出框分配的最佳方法是什么。

编辑:

有时您看不到它...感谢@Ron Gahlot - 通过简单的布尔检查解决:

- (BOOL)popoverShouldClose:(NSPopover *)popover
{
    // Check if imageSettings can close
    if ([popover.contentViewController isMemberOfClass:[SHWildcardItemSettingImageViewController class]])
        return ![[popover.contentViewController valueForKey:@"lockPopover"] boolValue];

return YES;

}

【问题讨论】:

  • 您也可以使用 NSPopOver 代表来管理这种情况 - (BOOL)popoverShouldClose:(NSPopover *)popover; - (void)popoverWillClose:(NSNotification *)notification;
  • 我也想过,但是这个解决方案也会跟踪弹出框旁边的点击(我想允许 - 那些应该关闭弹出框)。这不是弹出窗口 CLOSING ......这是我想要避免的 viewController 的 DEALLOCATING 直到我的 openDialog 完成。
  • openDialog 打开时使用 bool 变量在 popoverShouldClose 中返回 NO
  • 做到了。为帖子添加了解决方案。
  • 如果你有你的解决方案那么你能验证我的答案

标签: objective-c delegates xcode8 nspopover


【解决方案1】:

您使用布尔变量。当 openDialog 打开时返回 NO in - (BOOL)popoverShouldClose:(NSPopover *)popover;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-21
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-27
    • 1970-01-01
    相关资源
    最近更新 更多