Swift中的IBOutlets为空。

12

(在OSX 10.9,Xcode 6.1b上开发)

如果我在AppController中声明IBOutlets,一切都很好。我在InterfaceBuilder中实例化一个对象,将它拖到表单中,然后在applicationDidFinishLaunching到达时,我的IBOutlets已经填充好了,一切都很棒。

如果我更进一步的抽象,并在InterfaceBuilder中实例化一个自定义控制器对象(NSObject的子类),并在该类中将我的对象之一声明为IBOutlet,则它们都是nil,每个都是如此。

我可以很好地设置连接,IB似乎相信它存在,'referenced outlets'列表是正确的,但它没有意义,在文档中我也找不到除

  

它是隐式解包的,因为在从storyboard或xib文件初始化您的类之后,您可以假定已连接出口。

嗯,我曾经那样想过。

所有我的代码都是Xcode提供的样板:

@IBOutlet weak var sceneController: NSArrayController!

我已经检查了连接,进行了双重检查和三重检查。我看了几十个iOS教程(虽然我找不到OSX的等效教程),所有这些教程似乎都是围绕“是的,你绝对可以在AppController之外的文件中声明出口,只要确保每个涉及的实例都存在”这一主题的变化。

(撰写时,“mac”文档使用了UIButton等示例)

我没有任何想法。显然,连接没有形成,可能是因为对象的实例化顺序不同于'控制器类首先,IBOutlets稍后',但是我如何强制进行这种连接?


我有同样的问题。你找到任何解决方案了吗? - kokluch
请看我的评论,将@objc添加到接收类中,并运行'clean'操作确实有所帮助。(自那以后我就没遇到过这个问题)。目前(6.1版本),我遇到了很多“无法找到类x的详细信息”的问题(包括AppController类),我通过编写IBAction/IBOutlet代码、运行'clean'操作并从类到nib文件建立连接来规避这个问题。 - green_knight
3个回答

5
@IBOutlet weak var sceneController: NSArrayController!
< p >问题在于 weak 关键字。如果系统完成解码您的 nib 文件之后,没有任何其他引用 NSArrayController 的内容,那么系统将立即将 outlet 设置为 nil 并释放 NSArrayController

尝试从您的 outlets 中删除 weak 关键字。

更新

添加此代码:

@IBOutlet var sceneController: NSArrayController! {
    didSet {
        NSLog("sceneController set to %@", sceneController);
    }
}

输出是什么?在NSLog上设置断点。当它被命中时,堆栈跟踪是什么?它是否被重复命中?


谢谢您的建议,这是我没有尝试过的一件事情,因为我的理解是在nib文件中实例化一个项目意味着nib文件对该项目有强引用。可悲的是,这不是解决方案:我知道控制器存在,因为它填充了一个表格,并且删除“weak”没有任何区别,所以这是关于outlet未设置的问题。 - green_knight
在setter方法上设置一个断点,看看它是否被调用。 - rob mayoff
没有setter方法。据我所知,InterfaceBuilder应该在nib完成加载后解析IBOutlet指令,但它没有这样做。我从未见过在代码中设置IBOutlet的方法,因此唯一的解决方法似乎是在applicationDidFinishLaunching中强制实例化并手动设置连接?那将导致非常混乱的代码 :-( - green_knight
1
使用 IBOutlet 上的 didSet 帮助我检查了一下,它们确实没有被设置。每次我测试时,苹果都会推出新版本的 Xcode,GM1 给我带来了很多问题。在 GM2 中,错误消息已经改变了。两个看似必要的步骤:对于您想要具有 IBOutlet 属性的类,请使用 @objc(className),并使用“clean”使该更改生效,否则 IB 将无法识别该类。我怀疑这一直是问题所在,只是现在的错误消息更清晰了。 - green_knight
2
弱化也没关系。我有@objc,但没有@objc(className)。显然需要(className),这太荒谬了。 - n8tr
谢谢Rob +1 :) - Marin

1

当我在viewWillAppear方法中配置按钮的圆角时,出现了问题。将此部分代码移动到viewDidLoad方法中解决了该问题。


我会记下来的 - 我已经好几年没有遇到这个问题了(并且使用了几个Xcode版本),所以我认为它已经被修复了。(现在有一些变化,苹果公司建议outlets应该是strong类型。) - green_knight

1
我遇到了类似的问题。
我有一个按钮,可以将我从一个视图控制器带到另一个视图控制器。在此按钮的事件处理程序中,我尝试为第二个视图中的一些 GUI 组件设置值。不幸的是,这些组件的值为 nil。
解决方案是等待按钮处理程序退出后,在第二个视图中对 GUI 组件进行更改(尝试第二个视图控制器上的 viewDidLoad() 函数)。可能在我离开处理程序并切换视图之前,那些 GUI 组件没有被分配。
yuen helbig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接