After the Swift 3 conversion, I can’t get rid of the error: "Ambiguous use" indexOfObject (passTest :) ")

I am using NSArray indexesOfObjects (passTest :), but after I converted my code to Swift 3, I get the error: "Ambiguous use" indexOfObject (passTest :) ". My code below worked fine with 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 } }) 

For Swift 3, I also had to drop constraint to AnyObject , but this does not AnyObject actual problem.

I ended up using func indexesOfObjects(options: NSEnumerationOptions = [], passingTest: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Bool) with an empty array for the parameters, as shown below. This works, but I still don’t understand why I get the "Ambiguous ..." error with my initial implementation.

 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 } }) 
+6
ios ios10 swift3 compiler-errors ambiguous
source share
1 answer

In Objective-C, two indexesOf methods are two different methods:

 - (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); 

And now, Swift 3 imports these ambiguous two methods:

 @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 

One is indexesOfObjects(passingTest:) , and the other is indexesOfObjects(options:passingTest:) . And unfortunately, Swift 3 gave a default value for the options parameter, which made a simple call like bubbleConstraints.indexesOfObjects(passingTest: ...) ambiguous.

It can cause

  • indexesOfObjects(passingTest:)

or

  • indexesOfObjects(options:passingTest:) with default options

(Swift should not give a default value if it causes this ambiguity. Better send an error report.)

In this case, your workaround using indexesOfObjects(options:passingTest:) should work, but there is another work around:

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

The .indexesOfObjects(passingTest:) method indexesOfObjects(passingTest:) returns the indexesOfObjects(passingTest:) method as a closure, and the above expression calls it.


By the way, it is better to use the Swift collection methods rather than using the NSArray method:

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

All Articles