Is NSSortDescriptor thread safe?
I have a setter for a class that I was wanting to have input sorted on setting (it's called infrequently enough the cost is OK), and I was thinking to help make it a little faster I'd create a static NSSortDescriptor to use since the sorting parameters are always the same.
The setter is meant to be atomic though, and I开发者_开发技巧 was wondering if it's safe to use the same instance of NSSortDescriptor across multiple threads outside of an @synchronized block (since I was going to sort the incoming array before I entered the @synchronzied block). Is the following code thread safe? Or is this too much premature optimization?
- (void) setMyArray:(NSArray*)newMyArray
{
static NSArray *sorter = nil;
@synchronized(self)
{
if ( sorter == nil )
{
NSSortDescriptor *sortObj = [NSSortDescriptor sortDescriptorWithKey:@"size" ascending:YES];
sorter = [[NSArray arrayWithObject:sortObj] retain];
}
}
NSArray *sorted = [myNewArray sortedArrayUsingDescriptors:sorter];
@synchronized(self)
{
// set iVar from sorted array...
}
}
The documentation specifically states:
Immutable objects are generally thread-safe; once you create them, you can safely pass these objects to and from threads. Of course, when using immutable objects, you still need to remember to use reference counts correctly. If you inappropriately release an object you did not retain, you could cause an exception later.
Since, as hoha observed, NSSortDescriptor is immutable, it is thread safe unless specifically noted otherwise (typically in the class documentation).
NSSortDescriptor
doesn't have any visible ways to change it and it doesn't have any reasons to change its state internally so it is most probably thread-safe (unless Apple do hacks on it in framework code which I doubt).
As for optimization it is (almost) always premature without actual profiling. In this case though I'll do the same thing with static var - mostly to have a place where my sort strategy is clearly declared/defined.
精彩评论