I'm using NSArray
's indexesOfObjects(passingTest:), but after I converted my code to Swift 3 I get the error: "Ambiguous use of 'indexOfObject(passingTest:)'".
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 cast constraint
to AnyObject
, but that doesn't fix the actual problem.
I ended up using func indexesOfObjects(options: NSEnumerationOptions = [], passingTest: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Bool)
with an empty Array for options as below. This works, but I still don't understand why I'm getting the "Ambiguous..." error with my original 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
}
})
In Objective-C, the two indexesOf
methods are distinct two 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 import those as 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 another is indexesOfObjects(options:passingTest:)
. And unfortunately, Swift 3 has given a default value for the parameter options
, which has made a simple call like bubbleConstraints.indexesOfObjects(passingTest: ...)
ambiguous.
It may be calling
indexesOfObjects(passingTest:)
or
indexesOfObjects(options:passingTest:)
with giving default value to options
(Swift should not give a default value, if it causes this sort of ambiguity. Better send a bug report.)
In this case, your workaround code, using indexesOfObjects(options:passingTest:)
should work, but there is another work around:
bubbleConstraints.indexesOfObjects(passingTest:) {constraint, idx, stop in
//...
}
The method reference .indexesOfObjects(passingTest:)
returns the method indexesOfObjects(passingTest:)
as a closure, and the above expression is calling it.
By the way, you better consider using Swift's collection methods, rather than using an NSArray
s method:
let indexesOfBubbleConstraints = bubbleConstraints.enumerated().lazy
.filter {(idx, constraint) in
//...
}.map{$0.offset}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With