Use
[NSPredicate predicateWithFormat:@"id != %@", @"40"]
or
[NSPredicate predicateWithFormat:@"id != %@", @40]
depending on whether the id is stored as a string or as a number.
Note that you can simplify your code to
[_groupCategoryCurrentIds filterUsingPredicate:...];
if _groupCategoryCurrentIds
is a mutable array.
"IN" in a predicate is used for testing membership in an array or set, for example
[NSPredicate predicateWithFormat:@"NOT id IN %@", @[@40, @50]]
to get all objects where the id is neither 40 nor 50.
Using "IN" with a string on the right-hand side is not documented in the Predicate Programming Guide. It seems to behave like "is a substring of", so that in your case
[NSPredicate predicateWithFormat:@"NOT id IN %@", @"40"]
gives all objects where the id is not a substring of "40". That would explain your result. But again, this is not documented behaviour.