2012-05-24 8 views
26

Słyszałem, że leniwe tworzenie obiektów w systemie iOS jest dość powszechne, ale nie jestem do końca pewien, kiedy powinienem go użyć. Czy ktoś mógłby dać krótkie wyjaśnienie, kiedy powinienem użyć leniwego tworzenia i kiedy powinienem zainicjować moje właściwości w metodzie init?Kiedy używać leniwego tworzenia wystąpień w systemie iOS?

Moja troska dotycząca leniwego tworzenia instancji polega na tym, że wymaga ona dużej ilości kodu (w porównaniu z napisaniem wszystkiego w metodzie init), szczególnie jeśli masz wiele właściwości do zainicjowania.

+0

W jaki sposób wymaga dużo kodu w porównaniu do robienia tego w init? Zasadniczo nie robi to nic więcej, niż robi rzeczy w init. –

+0

Nie ma sensu w małych projektach i na nowych urządzeniach. Jeśli interesujesz się pamięcią, musisz użyć leniwego tworzenia instancji. – ymutlu

+0

@ymutlu Czy możesz wyjaśnić, dlaczego nie ma to sensu w małych projektach i przy użyciu nowych urządzeń? –

Odpowiedz

18

Aby opracować mój komentarz. Czasami ta technika jest dobra, jeśli masz obiekt, który musi zostać skonfigurowany tylko raz i wymaga pewnej konfiguracji, której nie chcesz zaśmiecać metodą init.

- (UIView *)myRoundedView; 
{ 
    if (!_myRoundedView) { 
     _myRoundedView = [[UIView alloc] initWithFrame:<#some frame#>]; 
     _myRoundedView.layer.cornerRadius = 10.f; 
     _myRoundedView.backgroundColor = [UIColor colorWithWhite:0.f alpha:0.6f]; 
     _myRoundedView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 
    } 
    return _myRoundedView; 
} 

Jest to dość wymyślny przykład, ale można zacząć widzieć zalety. Metody powinny być jak zajęcia i dobrze robić jedną rzecz. Ta metoda powoduje zwrócenie żądanego zaokrąglenia. Jeśli dodałem ten kod do metody init, to metoda init będzie musiała teraz znać szczegółowe szczegóły, jak utworzyć i skonfigurować ten widok oraz inne obiekty, które tam wpadam.

11

Tak jak w przypadku każdej techniki, nie ma jednej, uniwersalnej reguły, która wskazywałaby, kiedy leniwie tworzyć coś. Uważam, że dobrą radą jest używanie leniwych instancji dla rzeczy, które są kosztowne do utworzenia wystąpienia. Jeśli coś wymaga dużej ilości dostępu do dysku lub sieci lub wymaga dużo czasu procesora, lepiej odłożyć tę pracę, dopóki nie będzie to konieczne (lub zrobić to w tle). Zwłaszcza w przypadku funkcji, których użytkownik może używać lub nie, nie ma sensu marnowanie zbyt wiele czasu w ustawieniach -init (lub podobnych), co może przyczynić się do spowolnienia działania aplikacji dla użytkownika.

Dzięki temu powinieneś unikać przedwczesnej optymalizacji. Nie poświęcaj dużo czasu na pisanie skomplikowanego kodu, aby pomóc w wydajności, dopóki nie zrobisz rzeczy w oczywisty sposób, nie natrafisz na problem z wydajnością i sprofilujesz swój kod, aby dokładnie zrozumieć problem. Gdy to zrobisz, możesz zacząć wprowadzać zmiany, aby poprawić.

13

Jest to dobre rozwiązanie w sytuacjach, w których istnieją obiekty, które mogą mieć duży rozmiar pamięci, dzięki czemu można uniknąć inicjowania wszystkich tych kosztownych obiektów w momencie inicjowania klasy kontenera. Lazy inicjalizacji może zachować zużycie pamięci w kilku sytuacjach ...

Jednak jest oczywiste, że jeśli wszystkie obiekty wymagają inicjalizacji po lub natychmiast po inicjalizacji obiektu kontenerowego, inicjowanie leniwy nie ma sensu i standardowy konstruktor należy użyć inicjalizacji.

Należy użyć inicjalizacji leniwej, jeśli w klasie są obiekty opcjonalne, których nie można zainicjować podczas całego przepływu pracy w klasie.

3

Nie tylko dla pamięci i wydajności, to sprawdzić, oto kolejny przykład:

- (NSArray *)validElements{ 
    if (!_validElements) { 
     _validElements = [[NSArray alloc] initWithObjects: 
          @"mystuff",@"generaldescription",@"title",@"autor", 
          @"version",@"date",@"context",@"operatingsystem",@"kindofdevice", 
          @"deviceversion",@"rule",@"daytime",@"time",@"location",@"deviceheading", 
          @"region",@"language",nil]; 
    } 
    return _validElements; 
} 

Można użyć leniwy konkretyzacji do prowadzenia niestandardowej metody init lub specjalnej konfiguracji i tak też to korzyści pamięć i wydajność.

Powiązane problemy