Reputation: 31283
I have a class called Option
. This is a Realm object so it's a subclass of Realm's own base class Object
.
In a view controller I have an array property that holds a bunch of Option
objects.
private var options = [Option]()
In a method down the view controller, I need to check if a certain Option
object is contained within the aforementioned options array.
Previously (Swift 1.2), I have the checking logic like this.
func itemSelected(selection: Object) {
let option = selection as! Option
if !contains(options, option) {
// act accordingly
}
}
Now I'm converting the project to Swift 2 (I have updated the Realm's version to Swift 2 version as well). I updated the code to this.
func itemSelected(selection: Object) {
let option = selection as! Option
if !options.contains(option) {
// act accordingly
}
}
But now I'm getting the following compile error!
Cannot convert value of type 'Option' to expected argument type '@noescape (Option) throws -> Bool'
I can't figure out why. Any ideas?
Upvotes: 4
Views: 3581
Reputation: 223
While the first answer, that indicates this issue occurs because the contains
method needs to operate on an Equatable
type, is true, that's only half the story. The Realm Object
class inherits NSObject
, which conforms to Equatable
(thus this should work without a closure). For more discussion on this, you can refer to this issue on the Realm GitHub page: https://github.com/realm/realm-cocoa/issues/2519. The Realm developers indicate that they believe this is a bug in Swift.
Ultimately, the suggested workaround is to re-declare the conformance to Equatable
and Hashable
, like so (this is copied verbatim from GitHub user bdash's comment on the previously posted issue):
public class A: Object, Equatable, Hashable {
}
public func ==(lhs: A, rhs: A) -> Bool {
return lhs.isEqual(rhs)
}
You'd replace the all instances of type A
with type Option
in that sample.
I've tested this solution, and it works for me in XCode 7.2.1, using Swift version 2.1.1.
Upvotes: 1
Reputation: 2913
This is because the contains
function now expects a closure rather than an element on all non-equatable types. All you need to do is change it to the following
if !(options.contains{$0==option}) {
// act accordingly
}
What this does is it passes a closure in to the function, which returns true only if that closure satisfies any of its elements. $0
stands for the current element in the array that the contains
function is testing against, and it returns true if that element is equal to the one that you are looking for.
Upvotes: 9