After Swift 3 conversion, I can't get rid of error: "Ambiguous use of 'indexOfObject(passingTest:)'"

After Swift 3 conversion, I can't get rid of error: "Ambiguous use of 'indexOfObject(passingTest:)'"

我正在使用 NSArray 的 indexesOfObjects(passingTest:),但是在我将我的代码转换为 Swift 3 之后,我得到了错误:"Ambiguous use of '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) 和一个空数组作为选项,如下所示。这行得通,但我仍然不明白为什么我的原始实现出现 "Ambiguous..." 错误。

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
        }
    })

在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:) returns方法indexesOfObjects(passingTest:)作为闭包,上面的表达式是在调用它。


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

let indexesOfBubbleConstraints = bubbleConstraints.enumerated().lazy
    .filter {(idx, constraint) in
        //...
    }.map{[=13=].offset}