&引用;使用';儿童'&引用;尝试在Swift 3.0中使用NSTreeController.arrangedObjects时
试图向不透明的&引用;使用';儿童'&引用;尝试在Swift 3.0中使用NSTreeController.arrangedObjects时,swift,swift3,xcode8,nstreecontroller,Swift,Swift3,Xcode8,Nstreecontroller,试图向不透明的NSTreeController.arrangedObjects对象发送消息时,我在XCode 8.0/Swift 3.0中遇到了一个使用“children”的模糊错误 下面是一个光秃秃的操场,展示了用例: import AppKit extension NSTreeController { func whatever () { let k = (self.arrangedObjects as AnyObject).children // error h
NSTreeController.arrangedObjects
对象发送消息时,我在XCode 8.0/Swift 3.0中遇到了一个使用“children”的模糊错误
下面是一个光秃秃的操场,展示了用例:
import AppKit
extension NSTreeController {
func whatever () {
let k = (self.arrangedObjects as AnyObject).children // error here
}
}
我尝试使用AnyObject
作为到底层ObjC对象的桥梁,我想它应该能够通过任何方法调用
Xcode表示它找到了两个可以响应“children”消息的候选者:Foundation.XMLNode
和AppKit.NSTreeNode
当然,显而易见的解决方案(强制转换为NSTreeNode
)不起作用,因为arrangedObjects
返回的是不透明的代理对象,而不是真实的NSTreeNode
关于如何在Swift 3中使用NSTreeController.arrangedObjects.children
的任何建议?两个children
属性的候选对象因其类型而异:
Foundation.XMLNode:137:14: note: found this candidate
open var children: [XMLNode]? { get }
^
AppKit.NSTreeNode:12:14: note: found this candidate
open var children: [NSTreeNode]? { get }
^
您可以通过强制转换属性的值来解决歧义
设置为所需的类型。就你而言:
let k = (self.arrangedObjects as AnyObject).children as [NSTreeNode]?
另一种解决方案:向NSTreeController添加Obj-C类别
H
现在,在您的代码中,您可以这样使用它:
return treeController.rootNodes() as? [NSTreeNode]
我对上面的答案有疑问:当“全模块优化”打开时,编译器拒绝编译。迅速的延期也没用。我使用的是Xcode 8.2.1。将排列对象
转换为实际类型,而不是任何对象
(排列对象为!NSTreeNode
)@vadian:正如我在问题中所说,arrangedObjects
不返回NSTreeNode
,因此强制转换在运行时失败。然后将其强制转换为实际返回的内容。不幸的是,没有这么简单。实际上,arrangedObjects
返回一个\u NSControllerTreeProxy
,它是一个非公共类。如果我尝试强制转换到它,它甚至不会编译(使用未声明的类型“\u NSControllerTreeProxy”
)。代理对象保证只响应几条消息,其中一条是子对象
,不应在其他情况下使用。我没有使用NSTreeController的经验,无法测试它是否正常工作,但让k=(self.arrangedObjects as AnyObject)。子对象为[NSTreeNode]至少可以编译。就我所知,这是唯一有效的解决方案。我经常使用#selector(children())
和类似的工具,但都没有用。似乎在Xcode 8.2.1中,“整个模块优化”编译器选项不起作用。@LShi我稍后会再次检查它。我试图将代码移动到NSTreeController
的快速扩展,这是一个名为rootNodes
的方法,在整个模块优化方面仍然没有运气。哇,谢谢你。您能告诉我您是如何发现这两个候选项包含子项的吗?
#import "NSTreeController+RootNodes_m.h"
@implementation NSTreeController (RootNodes_m)
- (NSArray *) rootNodes {
NSObject * arranged = self.arrangedObjects;
if ([arranged respondsToSelector: @selector(childNodes)]) {
return [arranged performSelector:@selector(childNodes)];
}
return nil;
}
@end
return treeController.rootNodes() as? [NSTreeNode]