NSPredicate and Concurrency


I am currently in the process of a Sendable "audit" for our codebase. While refactoring, I've stumbled across some usages of NSPredicate, which is explicitely marked as being not Sendable. Now my question would be, is this really the case and if so, why? For me a predicate seems to be safe to send over concurrent domains. Is this because the class is not final because its subclassed?

Thanks in advance for any help!

NSPredicate can store mutable data and do all sorts of wild things. For NSPredicate to be Sendable it'd have to be final (which would require an entirely different implementation) and all objects captured by it would have to be Sendable. Currently you can do things like +[NSPredicate predicateWithBlock:] with a non-sendable block, or even just [NSPredicate predicateWithFormat:@"foo = %@", obj] where obj is a non-Sendable object that supports isEqual:.

1 Like

Thanks for the quick reply!
Well, a class being final or not does not seem to make a difference for foundation types at least, since e.g. NumberFormatter being Sendable despite being an open class.
For the rest, I agree, didn't see that for whatever reason. But that also means there is no way of making a class Sendable if theres a (mutable) stored property holding a predicate then, am I right?

You can convert it to be an actor, which is a tool for protecting concurrent access to mutable state. Or isolate on a global actor. Or make it @unchecked Sendable and implement thread-safe access on your own.