Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.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
Macos 在OSX中访问(可选?)属性;标识符";NSView子类的错误导致访问错误_Macos_Swift_Optional - Fatal编程技术网

Macos 在OSX中访问(可选?)属性;标识符";NSView子类的错误导致访问错误

Macos 在OSX中访问(可选?)属性;标识符";NSView子类的错误导致访问错误,macos,swift,optional,Macos,Swift,Optional,由于我对OSX上的Swift编程相当陌生,这个问题可能包含一些需要澄清的要点 我有一个方法,它迭代给定NSView实例的所有子视图。为此,我获取类型为[AnyObject]的子视图数组,并一次处理一个元素 在某个时候,我想访问每个实例的标识符属性。此属性是通过NSView中名为NSUserInterfaceItemIdentification的协议实现的,该类型在文档中作为(可选)String?给出。为了得到那个标识符,我会写 var view : NSView = subview as NSV

由于我对OSX上的Swift编程相当陌生,这个问题可能包含一些需要澄清的要点

我有一个方法,它迭代给定
NSView
实例的所有子视图。为此,我获取类型为
[AnyObject]
的子视图数组,并一次处理一个元素

在某个时候,我想访问每个实例的
标识符
属性。此属性是通过NSView中名为
NSUserInterfaceItemIdentification
的协议实现的,该类型在文档中作为(可选)
String?
给出。为了得到那个标识符,我会写

var view : NSView = subview as NSView;
var viewIdent : String = view.identifier!;
第二行由编译器标记,错误表明
标识符
不是可选类型,而是类型
字符串
,因此是后缀运算符
无法应用

删除此运算符可以很好地编译,但会导致运行时错误
EXC\u BAD\u ACCESS(code=1,address=0x0)
,因为对于某些
NSButton
实例,
identifier
似乎是
nil

我甚至不能测试这个属性,因为编译器给我一个
字符串,在我尝试时它不能转换为UInt8

if (view.identifier != nil) {viewIdent = view.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!
    
    因为如果在我的示例之前保留这一行,它将不起作用,因为您通过添加感叹号将可选内容转换为非可选内容

    它还强制强制强制转换为字符串,但可能您的
    标识符
    是一个Int,因此您不应该使用这种声明,而是希望
    如果让…
    安全地展开并转换值

    EDIT2:

    你说我的例子没有编译。。。我测试我的每一个答案。在回答之前,我在操场上测试了这个,下面是一个屏幕截图:

    另外,在检查之后,我确认标识符是可选字符串,这是使用ALT+单击属性时Xcode给出的类型。文档是正确的。


    所以如果对你来说是不同的,那就意味着你有一个与此无关的不同问题;但是我对这个精确问题的答案仍然是一样的。

    我得到了错误消息
    条件绑定中的绑定值必须是可选类型。
    在编译时。同样,编译器认为它不是可选的,这应该确保在运行时没有分配给变量的
    nil
    值,但运行时必须处理可选值(在本例中为
    nil
    ),小心可能出现的混淆:如果像这里一样将可选声明为非可选:
    var viewIdent:String=view.identifier
    如果标识符为nil,则它将崩溃,因为您在非可选模式中转换了可选模式。:)关于你的编辑:我从来没有用过你提到的那句话。如果你阅读了我的全部问题,你就会意识到这行代码并没有在我的机器上编译。编辑标记上方的示例行也是如此,它们也不会编译。我有一种感觉,我的问题不是要打开一个可选值,而是要找出为什么(可能只是)我的系统会这样运行。对我来说,最明显的问题是苹果的文档与编译器已知的类型不匹配。你知道我怎样才能找出问题所在吗?请参阅我答案中的EDIT2。另外,我已经阅读了你的全部问题,非常感谢/哦,我不是故意粗鲁的。对此我很抱歉。我想说的是你的努力方向错了。虽然我非常确定如何打开可选文件并测试值的存在性,但我还是想知道编译器的行为,尽管我们正在讨论的属性有文档。我关于健壮性的问题更多的是关于一种预感,我可能遗漏了一些真正基本的细节,第三种属性。