2012-04-09 9 views
18

Czy istnieje sposób wskazania kompilatorowi, że obiekt klasy jest zgodny z protokołem?Czy obiekt klasy ObjC może być zgodny z protokołem?

Jak rozumieją, tworząc +(void)foo metody klasy AN instancja tego obiektu klasy będą miały te same metody jak metodami np. Tak więc, dopóki będę tworzył metody dla wszystkich wymaganych metod protokołów, mogę sprawić, aby obiekt klasy działał jako delegat.

Mój problem polega na tym, że w pliku nagłówkowym klasy wiem tylko, jak wskazać, że instancje klasy są zgodne z protokołem (jak to zwykle bywa). Tak więc najlepsze, co sobie wymyśliłem, to rzucić obiekt klasy:

something.delegate = (id<SomethingDelegate>)[self class] 

Jakieś pomysły?

pokrewne, ale różne: ObjC: is there such a thing as a "class protocol"?

Odpowiedz

17

To, co teraz robisz, jest poprawne, ponieważ spowoduje wyciszenie ostrzeżeń, które są Twoim celem. Będziesz wysyłać wiadomości klasy obiektu zdefiniowane w protokole dla instancji, co jest nieco mylące, ale środowisko uruchomieniowe nie obchodzi.

Pomyśl o tym w ten sposób: chcesz ustawić delegata na obiekt odpowiadający na komunikaty zdefiniowane w protokole. Twoja klasa to robi, a twoja klasa jest również obiektem. Dlatego powinieneś traktować swoją klasę jak obiekt zgodny z tym protokołem. Dlatego to, co napisałeś, jest całkowicie poprawne (w oparciu o to, co próbujesz zrobić).

Należy jednak pamiętać, że ta klasa nie będzie poprawnie odpowiadać na conformsToProtocol:. Zasadniczo jest to ogólnie w porządku dla delegatów konfiguracji (delegaci zwykle nie sprawdzają, czy klasa odpowiada — po prostu sprawdzają, czy może odpowiedzieć na selektor).

Na marginesie, jedno można zrobić składniowo jest:

Class<SomethingDelegate> variable = (Class<SomethingDelegate>)[self class]; 

Różnica polega na tym, że kompilator będzie używać metod klasy z protokołu zamiast komunikatów instancji. W twoim przypadku nie jest to jednak coś, czego potrzebujesz.

+1

Nadal potrzebna jest składnia wskaźnika. 'Klasa *'. –

+4

Nie potrzebujesz składni wskaźnika. 'Class' jest już wskaźnikiem (jest zdefiniowany jako' typedef struct objc_class * Class') Będziesz go potrzebował tylko wtedy, gdy potrzebujesz wskaźnika do klasy (co jest prawdopodobnie dość rzadkie). – wbyoung

+0

Nono, mam na myśli 'Class' jak w zastępczy, a nie "Klasy", jak w prawdziwym typie. Myślę, że źle odczytałem twój wpis. –

7

Nie ma Objective-C składni, aby wskazać, że metaklasa zgodny z protokołem.

Myślę, że można to zrobić w czasie wykonywania, za pomocą class_addProtocol w metaclass. Ale nie próbowałem tego.

Sądzę, że możesz również napisać na swojej klasie metodę +conformsToProtocol: i kłamać o swojej zgodności. Może to mieć nieoczekiwane skutki uboczne, ponieważ istnieje już +conformsToProtocol: na NSObject (oprócz -conformsToProtocol:).

Żadne z nich nie wyeliminuje potrzeby rzutowania, aby zamknąć kompilator. Po prostu użyj singletonu.

Powiązane problemy