【问题标题】:After Swift 3 conversion, I can't get rid of error: "Ambiguous use of 'indexOfObject(passingTest:)'"Swift 3 转换后,我无法摆脱错误:“Ambiguous use of 'indexOfObject(passingTest:)'”
【发布时间】:2017-01-26 21:53:03
【问题描述】:

我正在使用NSArray 的 indexOfObjects(passingTest:),但在将代码转换为 Swift 3 后,我收到错误消息:“不明确地使用 'indexOfObject(passingTest:)'”。 我下面的代码在 Swift 2.3 上运行良好。

let indexesOfBubbleConstraints = bubbleConstraints.indexesOfObjects(passingTest: { (constraint, idx, stop) in
        if let view = constraint.firstItem as? UIView{
            return view.tag == usernameTag
        }
        else{
            return false
        }
    })

对于 Swift 3,我还必须将 constraint 转换为 AnyObject,但这并不能解决实际问题。

我最终使用func indexesOfObjects(options: NSEnumerationOptions = [], passingTest: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Bool) 和一个空数组作为以下选项。这可行,但我仍然不明白为什么我的原始实现会出现“模棱两可...”错误。

let indexesOfBubbleConstraints = bubbleConstraints.indexesOfObjects(options: [], passingTest: { (constraint, idx, stop) in
        if let view = (constraint as AnyObject).firstItem as? UIView{
            return view.tag == usernameTag
        }
        else{
            return false
        }
    })

【问题讨论】:

    标签: ios compiler-errors swift3 ios10 ambiguous


    【解决方案1】:

    在 Objective-C 中,两个 indexesOf 方法是截然不同的两个方法:

    - (NSIndexSet *)indexesOfObjectsPassingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
    - (NSIndexSet *)indexesOfObjectsWithOptions:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
    

    现在,Swift 3 将它们导入为模棱两可的两种方法:

    @available(iOS 4.0, *)
    open func indexesOfObjects(passingTest predicate: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Bool) -> IndexSet
    
    @available(iOS 4.0, *)
    open func indexesOfObjects(options opts: NSEnumerationOptions = [], passingTest predicate: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Bool) -> IndexSet
    

    一个是indexesOfObjects(passingTest:),另一个是indexesOfObjects(options:passingTest:)。不幸的是,Swift 3 为参数options 提供了一个默认值,这使得像bubbleConstraints.indexesOfObjects(passingTest: ...) 这样的简单调用模棱两可。

    它可能正在调用

    • indexesOfObjects(passingTest:)

    • indexesOfObjects(options:passingTest:) 将默认值设置为 options

    (Swift 不应该给出默认值,如果它会导致这种歧义。最好发送错误报告。)

    在这种情况下,使用indexesOfObjects(options:passingTest:) 的解决方法代码应该可以工作,但还有另一种解决方法:

    bubbleConstraints.indexesOfObjects(passingTest:) {constraint, idx, stop in
        //...
    }
    

    方法引用.indexesOfObjects(passingTest:)将方法indexesOfObjects(passingTest:)作为闭包返回,上面的表达式正在调用它。


    顺便说一句,你最好考虑使用 Swift 的收集方法,而不是使用 NSArrays 方法:

    let indexesOfBubbleConstraints = bubbleConstraints.enumerated().lazy
        .filter {(idx, constraint) in
            //...
        }.map{$0.offset}
    

    【讨论】:

    • 非常详细的答案!我也感谢您的最后评论,并且一定会按照您的建议进行操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    相关资源
    最近更新 更多