2011-06-20 24 views
9

Mój zespół odkrył, że korzystaliśmy z różnych obiektów NSDateFormatter w całej naszej bazie kodu i zaczęliśmy się zastanawiać, w jaki sposób moglibyśmy uniknąć kosztu/zamieszania związanego z przydzielaniem/inicjowaniem popularnych formaterów w kilku osobnych miejscach.Shared NSDateFormatter - najlepsze praktyki?

Jednym z pomysłów było stworzenie kategorii na klasie NSDateFormatter, która zapewniałaby odniesienie do statycznej instancji powszechnie skonfigurowanego formatyzatora. Na przykład, używaliśmy „krótki czas” Date formatowania w kilku miejscach, i szukali, aby dodać następujące metody klasy:

@implementation NSDateFormatter (NSDateFormatter_PDDateFormatters) 

static NSDateFormatter * shortTimeFormatter = nil; 

+ (NSDateFormatter *) PDSharedShortTimeFormatter { 

    @synchronized([NSDateFormatter class]){ 

     if(shortTimeFormatter == nil){ 

      // Create new formatter for SHORT times (e.g. 12:00 pm) 

      shortTimeFormatter = [[NSDateFormatter alloc] init]; 
      [shortTimeFormatter setDateStyle: NSDateFormatterNoStyle]; 
      [shortTimeFormatter setTimeStyle:NSDateFormatterShortStyle]; 
     } 

     return shortTimeFormatter; 

    } 

    return nil; 
} 

@end 

Jednym z problemów mam z tego podejścia jest to, że nie są w tej chwili " ochrona "NSDateFormatter przed zmianą. Ponieważ formater jest zasadniczo "udostępniany" w całej naszej aplikacji, może to potencjalnie powodować problemy, jeśli innym obiektem była zmiana konfiguracji formatyzatora (np. Styl czasu/daty).

Ponieważ używamy tego wewnętrznie, nie jestem zbytnio zaniepokojony ryzykiem, że nasz zespół nadużywa tej funkcji (tj. Jest to mały zespół i wyraźnie komentowany).

Jednak zastanawiałem się nad najlepszymi praktykami.

Czy istnieje sposób na zwrócenie niezmiennego odniesienia do formatyzatora daty? Jeśli zwrócę kopię formatyzatora, czy jest to mniej kosztowne niż wykonanie przydziału/inicjałów, które teraz wykonujemy?

Czy jest tu inne podejście?

Będziemy z tym pracować, ale zawsze dobrze jest uzyskać informacje zwrotne na temat pisania "lepszego" kodu.

Odpowiedz

9

Zwykle nie martwisz się tym. Obj-C pozwoli ci bawić się soczystymi wnętrzami niemal wszystkiego. Nawet @private nie chroni przed -valueForKey:_thatFunPrivateIvar. A jeśli wszystko inne zawiedzie, możesz po prostu wywołać funkcje uruchomieniowe.

Jednak najprostszym rozwiązaniem jest ujawnienie interfejsu API, który wewnętrznie używa formatów buforowanych, ale nie zapewnia to dostępu do formatów, z których korzysta. Twój kod będzie wtedy używał +[Formatter shortTimeStringFromDate:] do robienia tego, co teraz robi Twój przykładowy kod. Formater, o którym mowa, mógł być leniwie przydzielony i można by było używać pamięci możliwej do usunięcia, dzięki czemu buforowane formatery mogły być usuwane w trybie LRU pod presją pamięci.

+0

W tym konkretnym przypadku, pomyślałem również o dodaniu "publicznego" API do 'NSDate' class:' [date PDShortTime] '. Następnie buforowany obiekt 'NSDateFormatter' jest dostępny tylko za kulisami. Dziękuję za odpowiedź! – thauburger

+0

Byłoby to również miłe jako kategoria na NSString, czyli/[NSString shortTimeFromDate:] – ADAM

+0

"Po prostu nie martw się o to" nie jest do zrobienia: jest to niezwykle łatwe do przypadkowego modyfikowania obiektów. Zdecydowanie zrób to obejście, które jest świetnym rozwiązaniem. –