Created
September 9, 2013 21:32
-
-
Save phughes/6501822 to your computer and use it in GitHub Desktop.
A thread safe way to parse dates with arbitrary formats. NSDateFormatter is not thread safe. This method keeps a collection of formatters,
one per thread per format, and creates/returns them in a thread safe manner. Caching formatter objects results in a significant speed improvement. On the simulator (2.4Ghz i5) we see the following numbers:
Fo…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// NSDateFormatter+fbsThreadSafeFormatter.h | |
// NSDateAdditions | |
// | |
// Created by Patrick Hughes on 3/3/13. | |
// Copyright (c) 2013 Patrick Hughes. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
@interface NSDateFormatter (fbsThreadSafeFormatter) | |
// NSDateFormatter is not thread safe. This method keeps a collection of formatters, | |
// one per thread per format, and creates/returns them in a thread safe manner. | |
/* Caching formatter objects results in a significant speed improvement. | |
On the simulator (2.4Ghz i5) we see the following numbers: | |
Formatting 10,000 date objects (single format, multiple threads): | |
Creating new formatter each time: 23.019063 seconds. | |
One formatter per thread: 1.352597 seconds. | |
*/ | |
+ (NSDateFormatter*)fbsFormatterWithFormat:(NSString*)format; | |
+ (NSDateFormatter*)fbsFormatterWithFormat:(NSString*)format usingTimeZoneAbbreviation:(NSString*)abbreviation; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// NSDateFormatter+fbsThreadSafeFormatter.m | |
// NSDateAdditions | |
// | |
// Created by Patrick Hughes on 3/3/13. | |
// Copyright (c) 2013 Patrick Hughes. All rights reserved. | |
// | |
#import "NSDateFormatter+fbsThreadSafeFormatter.h" | |
#import <objc/runtime.h> | |
static char const * const formattersKey = "formattersKey"; | |
static char const * const lockKey = "lockKey"; | |
@implementation NSDateFormatter (fbsThreadSafeFormatter) | |
+ (NSDateFormatter*)fbsFormatterWithFormat:(NSString*)format | |
{ | |
NSTimeZone *tz = [NSTimeZone localTimeZone]; | |
return [self fbsFormatterWithFormat:format usingTimeZoneAbbreviation:[tz abbreviation]]; | |
} | |
+ (NSDateFormatter*)fbsFormatterWithFormat:(NSString*)format usingTimeZoneAbbreviation:(NSString*)abbreviation | |
{ | |
NSCache *formatters = objc_getAssociatedObject(self, formattersKey); | |
NSLock *lock = objc_getAssociatedObject(self, lockKey); | |
if (!formatters) { | |
formatters = [[NSCache alloc] init]; | |
objc_setAssociatedObject(self, formattersKey, formatters, OBJC_ASSOCIATION_RETAIN); | |
} | |
if (!lock) { | |
lock = [[NSLock alloc] init]; | |
objc_setAssociatedObject(self, lockKey, lock, OBJC_ASSOCIATION_RETAIN); | |
} | |
// Create a key for the formatter based on the current thread's address and the desired format. | |
NSString *key = [NSString stringWithFormat:@"%p%@%@", [NSThread currentThread], abbreviation, format]; | |
[lock lock]; | |
NSDateFormatter *formatter = [formatters objectForKey:key]; | |
if (!formatter) { | |
formatter = [[NSDateFormatter alloc] init]; | |
[formatter setDateFormat:format]; | |
[formatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:abbreviation]]; | |
[formatters setObject:formatter forKey:key]; | |
} | |
[lock unlock]; | |
return formatter; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment