Loop through [AnyObject]? results in does not have a member named generator

后端 未结 2 722
借酒劲吻你
借酒劲吻你 2021-01-01 11:24

Why can\'t you loop through [AnyObject]? directly? What does it mean that there is no named generator? What is the proper technique for looping through an

相关标签:
2条回答
  • 2021-01-01 11:30

    screens returns an optional, so before using the actual value you have to unwrap - the recommended method is optional binding:

    if let screens = NSScreen.screens() {
        for screen in screens {
            var result : Bool = workspace.setDesktopImageURL(imgurl, forScreen: screen, options: nil, error: &error)
        }
    }
    

    Read more about Optionals

    Note that NSScreen.screens returns [AnyObject]?, so you might want to cast the array as [NSScreen] in the optional binding:

    if let screens = NSScreen.screens() as? [NSScreen] {
        for screen in screens {
            var result : Bool = workspace.setDesktopImageURL(imgurl, forScreen: screen, options: nil, error: &error)
        }
    }
    

    Addendum Answer to question in comment: why the error message says [AnyObject]? does not have a member named generator

    An optional is of a different type than the value it contains (an optional is actually an enum). You can iterate an array, but you cannot iterate over an integer or an enum.

    To understand the difference, let me make a real life example: you buy a new TV on ebay, the package is shipped to you, the first thing you do is to check if the package (the optional) is empty (nil). Once you verify that the TV is inside, you have to unwrap it, and put the box aside. You cannot use the TV while it's in the package. Similarly, an optional is a container: it is not the value it contains, and it doesn't have the same type. It can be empty, or it can contain a valid value.

    0 讨论(0)
  • 2021-01-01 11:44

    Here's an alternative that will save you one level of indentation:

    for screen in NSScreen.screens() ?? []  {
        var result : Bool = workspace.setDesktopImageURL(imgurl, forScreen: screen, options: nil, error: &error)  
    }
    

    Using the nil-coalescing operator (??) provides an empty array in case of nil, and Swift treats screens() as non-optional.

    0 讨论(0)
提交回复
热议问题