由于我对 OSX 上的 Swift 编程相当陌生,因此这个问题可能包含几个需要澄清的点。
我有一个方法可以迭代给定 NSView 实例的所有 subview 。为此,我获取了 [AnyObject]
类型的 subview 数组,并一次处理一个元素。
有时我想访问每个实例的identifier
属性。该属性是通过 NSView 中名为 NSUserInterfaceItemIdentification
的协议(protocol)实现的,该类型在文档中给出为(可选)String?
。为了获得该标识符,我会写
var view : NSView = subview as NSView;
var viewIdent : String = view.identifier!;
第二行被编译器标记为错误,指出 identifier
不是可选类型,而是类型 String
,因此后修复无法应用运算符 !
。
删除此运算符可以正常编译,但会导致运行时错误EXC_BAD_ACCESS(code=1,address=0x0)
,因为identifier
似乎是nil
code> 某些 NSButton
实例。
我什至无法测试此属性,因为编译器在我尝试时给了我一个String is not convertible to UInt8
if (view.identifier != nil) {viewIdent = view.identifier;}
我的问题是
- 文档是否有误? I.g.属性
identifier
不是可选的? - 如何解决这个问题并获得运行稳健的代码?
最佳答案
如果文档指出 view.identifier
是可选的,则意味着它可以为零。因此,对于某些按钮实例来说,它对您来说确实为零,这并不奇怪。
强制解开这个可能为零的元素将导致您的应用程序崩溃,您可以使用安全解开来代替:
if let viewIdent = view.identifier {
// do something with viewIdent
} else {
// view.identifier was nil
}
您可以轻松地检查 Xcode 中元素的类型:按住 ALT 键单击该元素。它将显示一个弹出窗口,其中包含信息,包括类型。您可以在那里验证您的元素是否为可选元素。
提示:您可以安全地在一行上打开多个项目,这相当方便:
if let view = subview as? NSView, viewIdent = view.identifier {
// you can do something here with `viewIdent` because `view` and `view.identifier` were both not nil
} else {
// `view` or `view.identifier` was nil, handle the error here
}
编辑:
在使用我的示例之前,您必须删除这一行:
var viewIdent : String = view.identifier!
因为如果您将此行保留在我的示例之前,它将不起作用,因为通过添加此感叹号将可选内容转换为非可选内容。
它还强制转换为 String,但也许您的 identifier
是 Int,所以您不应该使用这种声明,而更喜欢 if let ...
安全地解包并转换值。
编辑2:
你说我的例子无法编译...我测试了我在SO上所做的每个答案。在回答之前,我在 Playground 中测试了这个,这是一个屏幕截图:
此外,检查后,我确认该标识符是一个可选字符串,这是 Xcode 在对该属性使用 ALT+CLICK 时给出的类型。文档是正确的。
因此,如果您的情况有所不同,则意味着您遇到了与此问题无关的其他问题;但我对这个确切问题的答案保持不变。
关于macos - 在 OSX 中,访问(可选?) NSView 子类的属性 "identifier"会导致访问错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31110609/