4

I want to be able to do the following:

NSString *hoursAndMinutes = [myNSDateObject formattedTime]; // eg. 10:25

Now I can create a category on the NSDate class but since the creation of NSDateFormatter has proven to be quite costly I would like to use a single instance of my NSDateFormatter. Is this a contradiction to the notion of categories or is there a neater way to achieve this?

Besi
  • 22,579
  • 24
  • 131
  • 223
  • See [this answer](http://stackoverflow.com/a/6735644/581994) for an example of a category containing a static variable. – Hot Licks Jun 27 '12 at 17:34
  • 1
    You should be careful when creating instances of `NSDateFormatter` and reusing them. **`NSDateFormatter` is not thread-safe.** If the date formatter is used concurrently on two different threads, the application will crash. Make sure you use the date formatter on a single thread or provide a synchronization mechanism. – Nicolas Bachschmidt Jun 27 '12 at 17:45
  • Thanks for the remark. So I could make a queue and make sure that the formatter only ever runs in this queue? – Besi Jun 27 '12 at 18:12

3 Answers3

10

Categories will only let you maintain static variables. But for your instance that would work perfectly.

Make a category for your formatter as so

Header

@interface NSDateFormatter (myFormats)

+ (NSDateFormatter*) specialFormatting;

@end

Implementation file

@implementation NSDateFormatter (myFormats)

+ (NSDateFormatter*) specialFormatting{
    static NSDateFormatter *_specialFormatting;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _specialFormatting = [[NSDateFormatter alloc] init];
        // Continue Setting up this format;
    });
    return _specialFormatting;
}

@end

Then be sure to include your header where you want to use this (i use the prefix.pch file to include things I use all the time)

then you will not need to declare it and can use it from where it is. And the item will not be created each time you need it..

The object is never released. but that is what you desire anyhow. since it is still accessible it is not a memory leak.

You can also provide helper methods that will allow you to just get back the string.

Hope that helps.

The Lazy Coder
  • 11,560
  • 4
  • 51
  • 69
  • Can you quickly explain why you do `dispatch_once`. With static variables I used to do this: `if(!myStaticVar){ myStaticVar=...;}` – Besi Jun 27 '12 at 18:06
  • dispatch_once is guaranteed to only happen once. and the calculation to determine that it has been dispatched is handled for you. Since the call is static. dispatch_once will be encountered every time you call into the method. but the alloc and setup methods will only ever happen once per app execution. – The Lazy Coder Jun 27 '12 at 18:08
3

You can use a static variable for that (either at file scope or method scope) or you could wrap your NSDateFormatter inside a singleton to use from the category.

I would not say that this contradict the notion of category, but for sure using static variables or singletons is not always the nicest things to many programmers.

sergio
  • 68,819
  • 11
  • 102
  • 123
1

You can create static variables inside methods too.

bandejapaisa
  • 26,576
  • 13
  • 94
  • 112