2012-01-21 9 views
16

Biorąc pod uwagę to:Jak instancję klasy w Objective-C, które nie dziedziczą z NSObject

Person.h:

@interface Person 
{ 
} 
- (void) sayHello; 
@end 

Person.m:

#import "Person.h" 

@implementation Person 

- (void)sayHello 
{ 
    printf("%s", "Steve"); 
} 

@end 

Jak zrobić tworzysz Osobę? Próbowałem to:

Person *p = [Person new]; 

To nie działa, ani tym:

Person *p = [Person alloc]; 

[UPDATE]

zapomniałem powiedzieć, ja już próbowałem dziedziczy z NSObject, nowy i Alloc Prace. Jestem po prostu ciekawy, czy możemy utworzyć instancję klasy, która nie dziedziczy po NSObject?

+8

Co jest nie tak z 'Person' dziedziczącym po' NSObject'? – Costique

+0

+1, ponieważ jest to bardzo interesujące pytanie, chociaż praktyczna wartość może być bardzo mała. – vikingosegundo

+0

@Costique: Nic, po prostu istnieje wiele tutoriali, które znalazłem w Internecie nie wspominając, że jest to wymaganie (tj. Dziedziczenie z NSObject). przykład: http://pl.wikibooks.org/wiki/Objective-C_Programming/syntax Próbowałem dziedziczyć z Object, ale '[Person new]' nie działa zbyt – Hao

Odpowiedz

28

Absolutnie możesz to zrobić. Twoja klasa musi sama wdrożyć kod +alloc, tak jak robi to NSObject. Zasadniczo oznacza to użycie malloc(), aby pobrać fragment pamięci wystarczająco duży, aby pasował do struktury definiującej instancję klasy.

Zarządzanie pamięcią liczoną z wartością odniesienia również byłoby miłe (retain/release); jest to faktycznie część NSObjectprotocol. Możesz także zaadaptować protokół i wdrożyć te metody.

Dla porównania, można spojrzeć na the Object class, który jest pierwiastkiem klasa ObjC jak NSObject, że Apple zapewnia w swoim repozytorium open source dla Objective-C Czas pracy:

@implementation Object 

// Snip... 

+ alloc 
{ 
    return (*_zoneAlloc)((Class)self, 0, malloc_default_zone()); 
} 

// ... 

- init 
{ 
    return self; 
} 

// And so on... 

Mając na uwadze powyższe, należy pomyśl o NSObject jako integralnej części środowiska uruchomieniowego ObjC. Nie ma najmniejszego powodu, aby zaimplementować własną klasę root poza ciekawością, badaniem lub eksperymentowaniem (co jednak nie powinno być w ogóle zniechęcane).

+5

+1 To jest absolutnie poprawna odpowiedź. Naprawdę, jedyny * czas, kiedy nie chcesz dziedziczyć po 'NSObject', to kiedy będziesz robił coś * zasadniczo innego * pod względem zarządzania pamięcią. –

+0

Dogłębna odpowiedź dotycząca celu c, która wykracza poza: "Kliknij ten błyszczący przycisk w XCode" ... Awesome! +1 –

+0

Czy ta odpowiedź dotyczy również szybkich? – user3797599

-6

nie można ..

Alloc i nowy ..copy startowych Wszystkie te metody są określone w NSObject ..

Nie można również tworzyć własne, ponieważ Apple nie dostarczaj klasę implementacji NSObject ... musisz dziedziczyć z NSObject lub jego podklasy, aby można było zainicjować klasę

+2

oczywiście jest to możliwe. Apple też to zrobił. musisz "po prostu" zrobić własne zarządzanie pamięcią w stylu C. NSObject nie jest częścią języka Objective-C, podobnie jak Foundation, UIKit, AppKit, ... – vikingosegundo

+1

Nie rozumiem, dlaczego nie usunąłeś tej odpowiedzi, gdy jest ona tak wyraźnie błędna. Zdobądź odznakę Peer Pressure! :) –

4

Musisz:

  1. Dziedziczenie z NSObject,
  2. Do klasy A "biednych" z własnymi mallocs, itp, lub
  3. Zastosowanie Objective-C++ i utworzyć klasę C++.

Oczywiście żaden z dwóch pozostałych nie pasuje do zarządzania pamięcią C, a ich protokoły rozmów itp. Są różne.

+2

Prawie! Dla 2 możesz po prostu zaimplementować + przydział, -retain, -release, etc ... pod względem malloc i twojego własnego refcount. Wdrażając protokół NSObject *, możesz w przejrzysty sposób uczestniczyć w wielu rzeczach. –

+0

-1 nie * masz * dziedziczyć po 'NSObject'. Istnieje kilka klas, które nie są takie, jak 'NSProxy'. –

+1

@DaveDeLong on oznacza, że ​​musisz * albo * zrobić 1. * lub * 2. * lub * 3. –

3

Istnieje (bardzo prawdopodobne) nie ma powodu, aby nie chcieć dziedziczyć po NSObject, ale istnieje wiele dobrych powodów, aby to zrobić.

Byłbym ciekawy co do przyczyny, dlaczego nie chcesz dziedziczyć po NSObject. Przypuszczam, że wynika to z braku wiedzy, a nie z rzeczywistej potrzeby.

Ale nawet bez znajomości tego powodu: Nie rób tego. Ciężko jest to zrobić tak dobrze, że nadal jest przyjemny w innych klasach Objective-C, ponieważ jest praktycznie niemożliwy.

W każdym razie, tworzysz swoje obiekty w sposób, który ukrywa to, co naprawdę zostało zrobione.Podczas gdy w Javie, zwykle tworzyć instancje metodą domyślnego konstruktora new, w Objective-C jest utworzenie instancji poprzez wywołanie alloc na klasie, a następnie init na przykład:

Person *aPerson = [[Person alloc] init]; 

(Jest możliwe po prostu użyć Person new, ale nie zrobiłbym tego, ponieważ ukrywa to, co naprawdę zostało zrobione od ciebie)

Wdrażasz swoją klasę tak, że dziedziczysz od NSObject, a następnie, jeśli to konieczne, napisz własną metodę init.

Jeśli chcesz się zalogować do konsoli, użyj NSLog:

NSLog(@"Hello %@", @"Steven"); 

(@"" jest specjalny konstruktor dla NSString Struny w Objective-C nie są tablicami bajtów, ale obiekty.).

+3

Oczywiście w Objective-C 'new' jest skrótem dla' wan/'init/init'. –

Powiązane problemy