2012-02-19 11 views
6

Istnieją dwie możliwości dla konstruktorów w Objective C/kakao:Dlaczego użyjesz konstruktora metody klasowej w porównaniu z alokacją/init?

1. konstruktora klasy

Product *product = [Product productWithIdentifier:@"Chocolate"]; 
// Use product 

2. Alloc/init Konstruktor

Product *product = [[Product alloc] initWithIdentifier:@"Chocolate"]; 
// Use product 
[product release]; 

Co zrobić

  • Używam metody klasy tylko dlatego, że wygląda czystiej i nie potrzebujesz wydania.
  • Widzę dużo alokacji/init - co jest zaletą robienia tego w ten sposób?

Moje pytanie

  • Która z nich jest lepsze? Czy to tylko kwestia gustu?

Kod

Dla kontekście klasy wyrobów miałby następujące:

+(Product *)productWithIdentifier:(NSString *)identifier_ { 
    return [[[[self class] alloc] initWithIdentifier:identifier] autorelease]; 
} 

-(Product *)initWithIndentifier:(NSString *)identifier_ { 
    self = [super init] 
    if (self) { 
     identifier = identifier_; 
    } 
    return self; 
} 

Odpowiedz

5

Jeśli używasz ARC, nie ma dużej różnicy między tymi dwoma. Jeśli nie używasz ARC, różnica jest niezwykle ważna.

Kombinacja zawiera odniesienie do posiadania. Oznacza to, że musisz później to zrobić. Wariant classnameWithFoo zwraca odwołanie niebędące właścicielem. Nie możesz tego zrobić pod release.

Jest to zgodne ze zwyczajowymi konwencjami nazewnictwa Cocoa. Wszystkie metody zwracają nieprzypadkowe (autoreleased) instancje, z wyjątkiem metod, które zaczynają się od alloc, copy, mutableCopy i new. Zwracają one swoje referencje, które musisz release.

Który z nich jest najczęściej kwestią gustu. Jeśli jednak potrzebujesz tymczasowych obiektów, które możesz szybko wyrzucić, wersja alloc powoduje nieco mniej wywołań metod (autorelease) iw pętli redukuje również maksymalny rozmiar pamięci. Jednak w większości przypadków ten obniżony koszt jest lekceważący.

+0

Tak blisko między tymi dwiema odpowiedziami, ale jest to trochę lepsze, ponieważ wspomina o problemie z pamięcią śladu. Ale znowu ta druga odpowiedź wspomina o "nawiązywaniu" połączeń. Chciałbym móc wybrać obie! –

+1

Ulepszyłem odpowiedź Sergio, aby to zrekompensować ;-) – DarkDust

5

IMO, największa różnica między tymi dwoma podejściami jest z faktem, że za pomocą „konstruktora klasy "otrzymujesz autoreleased obiekt; jest to najwygodniejsza opcja, gdy:

  1. przypisać przydzielony obiekt do właściwości retain;

  2. podczas tworzenia „tymczasowy” przedmiotów (myślę o różnych NSString metod, które budują ciąg z innym ciągiem: w wielu przypadkach zdarza się, musisz „łańcuch” takie połączenia; konstruktor pozwala „zapomnieć” o zarządzanie pamięcią);

  3. podczas dodawania obiektu do jakiegoś przedmiotu, który przytrzymuje go (myślę: addSubview)

W takich przypadkach składniowej zaletą „konstruktora klasy” jest wszystkim, ale myślę również, że kod "bezpieczniejsze" pod względem zarządzania pamięcią. Z drugiej strony, gdy tworzysz obiekt, aby przypisać go do właściwości assign (lub bezpośrednio do ivar, dla którego nie masz własności), wtedy alloc/init zrobi doskonale i będzie lepszy od "konstruktora" (IMO).

Ostatecznie zależy to od sposobu, w jaki zamierzasz używać przydzielonych obiektów. Konstruktor klas jest metodą wygodną.

Powiązane problemy