Neither. You should use an NSFetchRequest
with a predicate. Your patterns can accidentally fault the entire relationship, which is very expensive and not needed just to check for whether it contains one object. There are ways to be careful and not fault the entire relationship, but it's fragile (small changes to your search lead to huge changes in performance) and so it's better to be in the habit of using NSFetchRequest
rather than the collection for searching. I like to set my fetchLimit
to 1 in these cases so once it finds it, it stops looking.
For convenience, you may want to create a -containsFoo:
method on your managed object so you don't have to write the fetch logic all over the place.
Your two solutions above are subtly different. The first one tests whether there is an object in the collection that isEqual:
to itemOfInterest
. Your second solution tests whether there is an object in the collection at the same memory location as itemOfInterest
. For objects with custom isEqual:
logic, these can return different results. This means that solution 2 might be slightly faster for non-core data collections, but it's because you're actually testing a different thing, not because of object enumeration. (In reality, this is only true for small collections; see below.)
Why do you believe that solution 1 uses -objectEnumerator
?
As @James Raybould points out, you generally should not try to rewrite the built-in methods for performance reasons. If an isEqual:
version of Solution 2 were faster than Solution 1, wouldn't you think Apple would have implemented -containsObject:
using the code in solution 2?
In reality, the underlying CFSet
is implemented as a hash, so checking for containment is logarithmic rather than linear. Generally speaking, for large sets with reasonable hash functions, solution 1 will be faster. See the code for it in CFSet.c. Look for CFSetContainsValue()
. CFSet's implementation isn't guaranteed to stay the same, of course, but it's useful for understanding how performance concerns are generally addressed within Cocoa.