【问题标题】:Referencing variables on NSApp delegate Cocoa在 NSApp 委托 Cocoa 上引用变量
【发布时间】:2014-04-26 08:32:57
【问题描述】:

所以我在这里有点困惑。我有一个 Cocoa 应用程序,在 appdelegate 标头中,我声明了一个已在 Interfacebuilder 中连接的 NSDrawer,并且我正在根据上下文以编程方式设置其 contentView。内容视图包含连接到 Appdelegate 中各种功能的按钮。

@property (strong) IBOutlet NSDrawer *theDrawer;

当我的应用程序启动应用程序并在调试器中检查它时,“theDrawer”不是 nil 并且由 Interfacebuilder 正确实例化。在

现在,如果用户单击任何按钮,就会发现对 [[NSApp delegate] theDrawer] 的引用将被忽略,因为 theDrawer 为 nil。这对我来说没有意义。我尝试通过在应用启动时专门设置委托来解决此问题。

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
  [NSApp setDelegate:self];
}

我已经检查过 self.theDrawer 在那一点上不为零。但即使在我明确设置委托之后,任何未来对 [[NSApp delegate] theDrawer] 的调用都是零。

如何确保访问我的 App 委托上的变量?我的理解是调用 NSapp 委托将返回应用程序的唯一实例。

似乎当用户单击一个按钮时,这会创建一个新线程,并且 NSApp 委托将为所有变量返回 nil。

任何帮助表示赞赏

【问题讨论】:

  • 您不应该为此使用应用程序委托(这不是该类的用途)。为drawer属性添加一个带断点的setter,什么时候调用?
  • 我还应该在哪里放置一个我需要从应用程序的任何地方访问的变量? setter 在主线程启动后直接调用
  • 如果是视图类型对象,则在加载NIB的关联窗口或窗口控制器中声明出口。 NSApplication 和委托的存在是为了桥接应用程序和系统事件,而不是作为全局状态桶。

标签: objective-c cocoa delegates


【解决方案1】:

应用程序委托在 main.m 中的 main 中正确设置,您可以在项目的“支持文件”文件夹中找到它。通常它嵌入在NSApplicationMain() 中,我相信它在plist 中引用了NSMainNibFile,实际上主笔尖拥有应用程序委托对象实例。然而,Apple 并不完全清楚所有这些魔法是如何运作的。尽管如此,您不能在applicationDidFinishLaunching 中设置委托——这是一个委托函数!

但是,如果您使用的是NSMainNibFile 和非文档应用程序,则应用程序委托可能会设置为您的主 NIB 中的一个对象...在该 NIB 中,“文件的所有者”是 还有应用程序委托类,并且其他出口在 [NSApp 委托] 中是非零的,因为它是主 NIB 文件的所有者。通过NSMainNibFile,您可以在 App Delegate 类中创建 outlet,因为它是文件的所有者。

如果您创建第二个 NIB,访问代理会出现问题。您不想创建对象,因为它与 [NSApp 委托] 不同。您可以使用 Application 占位符对象并与“application.delegate”键路径绑定。但是您不能创建 outlet,因为应用程序委托不能是文件的所有者。

但这无关紧要,因为如果您有第二个 NIB 并为其创建出口,它们属于您已声明为该文件所有者的自定义视图控制器或窗口控制器子类。 即使第二个 NIB 会立即加载,那么应用程序委托应该实例化一个控制器实例来加载和拥有 NIB,如果你想要插座,它必须是一个自定义子类。

Apple 通过让应用程序委托类成为非文档应用程序中 MainMenu.xib 中主菜单“窗口”的所有者来打破这种模式......但这是因为菜单窗口有点特殊。你在 MainMenu.xib 之外做的任何事情都需要一个自定义的控制器类来拥有出口。

Additional discussion in this answer 关于应用委托实例。

【讨论】:

  • 嗨@Stevesliva,感谢您的回答,我的问题是我在 MainMenu.xib 中执行所有这些操作。我想做的就是打开和关闭主窗口的抽屉。我对该抽屉的内容有单独的视图控制器,但主抽屉是在 MainMenu.xib 中创建和管理的。据我了解,控制类(主应用程序委托)应该管理抽屉的行为,创建类来显示和隐藏抽屉。但是,如上所述,如果我要调用主应用程序的实例,则此抽屉变量为零,我不明白为什么。
  • 好的,只需阅读您提到的问题,这实际上完全符合我的问题。所以我会把你的答案标记为解决方案。谢谢
  • 这个答案也是我的。出于某种原因,这种射击自己的方式没有得到很好的记录,但是在我自己对它的回答的几周内,它在stackoverflow上出现了两次。 S.O.标准响应是关于什么属于委托的讲座,但是 XCode 设置 MainMenu.xib 的方式基本上混淆了这个问题,并且有特殊处理可以确保那里的 Delegate 对象与 NSApp 委托相同。在其他任何地方尝试它,你会感到沮丧。您应该避免代表拥有 outlet,但知道它们为什么是 nil 也很重要。
猜你喜欢
  • 2015-11-03
  • 1970-01-01
  • 2012-03-15
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
  • 2010-09-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多