无法形成对类NSTextView实例的弱引用

时间:2014-06-05 14:09:05

标签: swift

仅使用Swift,这是我在AppDelegate.swift中的代码:

import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet var window: NSWindow
    @IBOutlet var textField: NSTextView

    @IBAction func displaySomeText(AnyObject) {
        textField.insertText("A string...")
    }

    func applicationDidFinishLaunching(aNotification: NSNotification?) {
        // Insert code here to initialize your application
    }

    func applicationWillTerminate(aNotification: NSNotification?) {
        // Insert code here to tear down your application
    }


}

在界面构建器中,我连接了一个对象以接收来自按钮的输入,然后输出转到文本视图。当我按下按钮时,我正试图让文本视图填充一些文本。

我也用文本字段尝试了这个,并没有得到错误,但是发出“dong”错误声音并且它没有做任何其他事情。在Objective-C中,您必须使用(assign)参数才能根据我的理解使其工作。

我做错了什么?

6 个答案:

答案 0 :(得分:13)

使用@IBOutlet var scrollView: NSScrollView代替@IBOutlet var textField: NSTextView 然后在scrollView中创建一个返回documentView的属性。

import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet var window: NSWindow
    @IBOutlet var scrollView: NSScrollView

    var textField: NSTextView {
        get {
            return scrollView.contentView.documentView as NSTextView
        }
    }

    @IBAction func displaySomeText(AnyObject) {
        textField.insertText("A string...")
    }

    func applicationDidFinishLaunching(aNotification: NSNotification?) {
        // Insert code here to initialize your application
    }

    func applicationWillTerminate(aNotification: NSNotification?) {
        // Insert code here to tear down your application
    }
}

答案 1 :(得分:13)

由于Cocoa和AppKit的历史问题,您无法存储对NSTextView的弱引用。见details in the Clang documentationNSTextView中的NS_AUTOMATED_REFCOUNT_WEAK_UNAVAILABLE被标记为NSTextView,还有NSTextView.h要注意。

您是否尝试过Swift无主参考而不是弱,这有点像Objective-C的分配(您在Objective-C中用于{{1}}插座的内容)?< / p>

答案 2 :(得分:1)

我试图复制你描述的内容。我使用Xcode 6 beta 7创建了一个新的OS X应用程序。我在主窗体中删除了一个按钮和文本视图。

我认为您的问题是由于某种原因,与Text View对象的连接不正确。为了简化操作,我使用control-drag连接了对象,这会自动添加所需的代码。首先,我已连接文本视图。为此,请单击文本视图对象,直到选中“文本视图”。当我在我的Xcode版本中执行此操作时,第一次单击该对象时,会选择 Bordered Scroll View 。再次单击它然后选择剪辑视图。最后,再次单击它选择文本视图。现在我控制 - 从对象拖动到AppDelegate.swift代码(它有助于显示助理编辑器,以便您的表单UI和代码并排)。

通过这样做,我得到了这个小窗口:

enter image description here

请注意,类型是NSTextView,存储是弱的。我只需要添加名称并单击“连接”。这在AppDelegate.swift中添加了以下代码:

@IBOutlet var textField: NSTextView!

代码几乎与您拥有的代码完全相同,除了行末尾的!,它强制解开textField的值。

就这一点而言,您在问题中拥有的代码应该有效。

我建议的另一件事是不要使用insertText。根据Apple的NSTextView.insertText文档:

  

此方法是插入用户键入的文本的入口点   并且通常不适合其他目的。编程   最好通过对文本存储进行操作来修改文本   直接

据我了解,通过直接操作文本存储来对文本进行编程修改意味着处理NSTextView继承的NSText。因此,请使用NSText.string。这就是单击按钮操作在我的代码中的显示方式:

@IBAction func displaySomeText(sender: NSButton) {
    // If you want to add a new 'A string... ' every time you click the button
    textField.string! += "A string... "
    // otherwise just use
    //textField.string = "A string..."
} 

我添加了Button Action的方式与我通过控制拖动添加Text View Outlet相同,在这种情况下,选择NSButton作为发件人,而不是离开默认AnyObject

答案 3 :(得分:0)

@IBOutlet自动使属性弱IIRC,但弱不会自动使属性可选。但是要求弱属性是可选的,因为属性可以在任何时候被解除分配并且为零。所以你必须声明你的@IBOutlets是可选的。

import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet var window: NSWindow? // Optional
    @IBOutlet var textField: NSTextView?

    @IBAction func displaySomeText(AnyObject) {
        textField?.insertText("A string...") // Only call the method if the object exists
    }

    func applicationDidFinishLaunching(aNotification: NSNotification?) {
        // Insert code here to initialize your application
    }

    func applicationWillTerminate(aNotification: NSNotification?) {
        // Insert code here to tear down your application
    }
}

答案 4 :(得分:0)

“dong”错误是否表明响应者链存在问题?如果在插入文本之前在文本字段上调用becomeFirstResponder该怎么办?

答案 5 :(得分:-2)

要使用weak关键字

创建弱参考用户

示例:

@IBOutlet weak var myView: UIView

在你的情况下

@IBOutlet weak var textField: NSTextView