Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Swift插件访问Objective-C NSDocument子类的实例属性?_Objective C_Macos_Plugins_Swift3 - Fatal编程技术网

从Swift插件访问Objective-C NSDocument子类的实例属性?

从Swift插件访问Objective-C NSDocument子类的实例属性?,objective-c,macos,plugins,swift3,Objective C,Macos,Plugins,Swift3,目标是编写一个Swift插件,它可以访问Objective-C NSDocument子类的公共实例属性。主要的应用程序是Objective-C。该插件的目的是快速 主应用程序具有公共Objective-C文档界面: @interface ObjcNSDocument : NSDocument @property (nonatomic, readwrite) NSString *markdown; @property (nonatomic, readonly) NSString *html;

目标是编写一个Swift插件,它可以访问Objective-C NSDocument子类的公共实例属性。主要的应用程序是Objective-C。该插件的目的是快速

主应用程序具有公共Objective-C文档界面:

@interface ObjcNSDocument : NSDocument

@property (nonatomic, readwrite) NSString *markdown;
@property (nonatomic, readonly) NSString *html;

@end
合理的Swift对应物似乎是:

public class SwiftNSDocument: NSDocument {

    public var markdown: String = ""
    public var html: String = ""

}
以下Swift代码检索当前NSOK文档。然而,铸造失败

public func doFilter() {
    let dc = NSDocumentController.shared()
    if let document: NSDocument = dc.currentDocument {
        print("document.displayName = \(document.displayName)") // works OK
        let markdownSource = document as! SwiftNSDocument // FAIL: cannot cast as
    }
}
虽然我要求这是一般性的,但我的特殊测试用例是重写Objective-C插件,使其尽可能接近纯Swift

理想情况下,解决方案不需要包含来自应用程序的任何Objective-C代码。什么是可能的,即使不理想

额外观察

对于正在工作的Objective-C插件,插件项目中不包括应用程序的NSDocument子类
.h
文件

相反,Objective-C插件只有作为NSObject子类的单个相关属性

@protocol MarkdownSource <NSObject>
@property (readonly) NSString *markdown;
@end
其中Object-C中的
id
将是Swift
Any
。我尝试过各种向下投射,如:

 let markdownSource: MarkdownSource = (nsdocument as Any) as MarkdownSource
 let markdown: String = markdownSource.markdown

到目前为止,我还无法使用Swift中的一个所需属性将NSDocument子类向下转换为任何NSObject子类。

转换失败,因为文档的类型是
ObjcNSDocument
,而不是
SwiftNSDocument
。目前,Swift中没有任何设施可以提供Objective-C级可以衔接的Swift级,反之亦然。您必须在插件中的某个地方包含Objective-C类的声明(通过包含标题或其他方式)。尝试只使用Swift的目的是什么?@itai ferber为什么只使用Swift?了解什么是Objective-C最基本的需求,并用Swift编写新的代码。你在Objective-C中所做的角色转换碰巧有效,但原因是错误的。从技术上讲,这不是一个有效的强制转换,因为您的Objective-C类实际上不符合
MarkdownSource
协议;它之所以有效,是因为Objective-C在这种情况下是不安全的,而且足够动态-获取
MarkdowSource.markdown
转换为
[MarkdowSource markdown]
,而
文档
恰好响应了它,所以它有效。如果我执行
((id)someRandomObject.).markdown
,强制转换将盲目成功,但方法调用将失败。Swift不允许您进行这些无效强制转换,因为它只允许您进行方法调用,它可以静态地(尽可能多地)保证它们会成功。(是的,您可以使用Objective-C运行时来做某些事情,但这避免了静态安全性);dr:以这种方式施法是无效的,所以斯威夫特不会让你这么做。
public class MarkdownSource: NSObject {
    public var markdown: String = ""
}
 let markdownSource: MarkdownSource = (nsdocument as Any) as MarkdownSource
 let markdown: String = markdownSource.markdown