Delegaci w IOS-potrzebne Wyjaśnienie

Dopiero zaczynam rozwój IOS, ale mam kilka lat dev ASP.net przez C#. Szczerze mówiąc nigdy nie miałem prawdziwej potrzeby zrozumienia delegatów / wydarzeń itp. wcześniej wiem, że używam ich przy programowaniu sieci.formy, ale dużą część funkcjonalności zajmuje framework, za kulisami.

Więc teraz, gdy rozwijam się w IOS, jestem zmuszony spróbować zrozumieć, jak działają (zakładam tutaj, że teoria delegatów / zdarzeń jest taka sama w całym języków, może się mylę). W każdym razie, następujący wiersz kodu w IOS:

 if ([self.delegate respondsToSelector:@selector(startImporting:)])
 {
            [self.delegate startImporting:self];
 }

Czy mam rację myśląc, że w pseudo kodzie oznacza coś w stylu:

Jeśli metoda / Klasa wywołująca tę metodę ma w sobie metodę o nazwie 'startImporting', to wywołaj metodę' startImporting ' wewnątrz klasy wywołującej.

Mam nadzieję, że to jasne. Jeśli tak, to czy w zasadzie byłoby to takie samo jak posiadanie statycznej metody w C# , którą można wywołać z czymś like:
myImportClass.startImporting();

Prawdopodobnie nie, albo tak by to było zrobione. Więc, czy brakuje mi całego punktu delegatów, ich korzyści itp? Czytałem, czym są w kółko i chociaż ma to sens, nigdy nie klika, nigdy (w formularzach internetowych) nie widziałem korzyści z ich używania.

Staje się to coraz ważniejsze, ponieważ przechodzę do używania wyrażeń lambda w. Net i są one ściśle związane z delegatami w C# , więc chociaż mogę po prostu zacząć ich używać, wolałbym wiedzieć dlaczego i czym tak naprawdę są delegaci pożytku.

Author: Full Time Skeleton, 2012-01-28

3 answers

Wzór delegacji w Cocoa jest używany do informowania (raportowania postępów itp.) lub zapytanie (poproś o poświadczenia itp.) kolejny obiekt, nie wiedząc o nim zbyt wiele.

Zazwyczaj używa się protokołu, aby zdefiniować metody, które będą wywoływane przez delegata, a następnie delegat musi być zgodny z tym protokołem. Możesz także dodać metody, których delegat nie musi implementować (opcjonalnie). Kiedy to zrobisz, będziesz musiał zadzwonić-respondsToSelector:, ponieważ nie wiesz, czy delegat chce, aby dana metoda została wywołana lub nie.

Przykład:
Masz klasę, która coś produkuje, nazwijmy to Machine i pracownika klasy Worker. Maszyna musi być dostosowana do zadania:

Machine *machine = [[Machine alloc] init];
[machine prepareWithParameters:myParameters];

Teraz, gdy mamy maszynę, chcemy wyprodukować ogromną ilość Stuff:

[machine produceStuff];
Dobra, skończyliśmy. Ale skąd wiemy, kiedy Jednostka Stuff została wyprodukowana? Możemy mieć naszego pracownika stale stojącego obok naszej Maszyny i czekaj:
while (![machine isFinished]) {
    if ([machine didProduceStuff]) {
        Stuff *stuff = [machine producedStuff];
        [self doSomethingWithStuff:stuff];
    }
    else {
        // Get a very large coffee...
    }
}

Czy nie byłoby wspaniale, gdyby maszyna informowała nas automatycznie, kiedy skończy się produkcja jednostki Stuff?

@protocol MachineDelegate <NSObject>
@optional
    - (void) machine:(Machine *)machine didProduceStuff:(Stuff *)stuff;
@end

Dodajmy worker jako delegat machine:

Worker *worker;
Machine *machine = [[Machine alloc] init];
[machine prepareWithParameters:myParameters];
[machine setDelegate:worker]; // worker does conform to <MachineDelegate>

[machine produceStuff];

Kiedy Machine zostanie wykonane wyprodukowanie czegoś, to wywoła:

if ([[self delegate] respondsToSelector:@selector(machine:didProduceStuff:)])
    [[self delegate] machine:self didProduceStuff:stuff];

worker następnie otrzyma tę metodę i może coś zrobić:

- (void) machine:(Machine *)machine didProduceStuff:(Stuff *)stuff {
    [self doSomethingWithStuff:stuff];
    if ([machine isFinished])
        [self shutDownMachine:machine];

}

Czy to nie jest dużo bardziej wydajne i łatwiejsze dla pracownika? Teraz może zrobić coś więcej produktywne niż stojąc obok maszyny, podczas gdy maszyna nadal produkuje. Możesz teraz dodać jeszcze więcej metod do MachineDelegate:
@protocol MachineDelegate <NSObject>
@required
    - (void) machineNeedsMaintenance:(Machine *)machine;
    - (void) machine:(Machine *)machine fatalErrorOccured:(Error *)error;
    - (BOOL) machine:(Machine *)machine shouldContinueAfterProductionError:(Error *)error;
@optional
    - (void) machineDidEnterEcoMode:(Machine *)machine;
    - (void) machine:(Machine *)machine didProduceStuff:(Stuff *)stuff;
@end

Delegaty mogą być również używane do zmiany zachowania obiektu bez jego podklasowania:

@protocol MachineDelegate <NSObject>
@required
    - (Color *) colorForStuffBeingProducedInMachine:(Machine *)machine;
    - (BOOL) machineShouldGiftWrapStuffWhenDone:(Machine *)machine;
@end

Mam nadzieję, że pomogę ci zrozumieć korzyści płynące z abstrakcyjnego kodu przy użyciu delegatów.

 45
Author: Fabian Kreiser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-01 19:18:22

Zrozumienie modelu MVC oraz wykorzystanie protokołów i powiadomień ma kluczowe znaczenie dla zrozumienia wykorzystania i celu delegatów. Pomyśl o nich jako o rodzajach reagowania na różne zdarzenia związane z konkretnym działaniem.

Hera to kilka przydatnych linków w stackOverflow:

Hope it helps

 1
Author: aracknido,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:53:59

Delegaty są przydatne w pobieraniu wywołań zwrotnych z innej klasy

Więc po co używać delegata: to nazywamy metodą na klasie... to normalne... jeśli chcemy, aby instancyjna Klasa pozwoliła nam oddzwonić... i tu przydają się delegaci...

Prosty przykład: Ściągasz piosenki z serwisu metodą na jednej klasie gdy Klasa zakończy pobieranie, chcesz, aby Klasa dała Ci znać.

 //protocol declaration
  @protocol DownloadProtocol <NSObject>
  -(void)OnFinish;
  @end

//SOng download class
@interface songs
@property(Strong,nonatomic) id<DownloadProtcol> delegate;
-(void)Download;
@end
@implementation songs
-(void)Download
{

///the code to download goes here

[self callTheCallingClass];

}

-(void)CallTheCallingClass
{
 [self.delegate OnFinish];
}
@end

//
@interface mainclass<DownloadProtocol>

@end

@implementation mainclass

-(void)viewDidload
{
Songs *s=[[SOngs alloc]init];
s.delegate=self;
[s download];
}
-(void)OnFinish
{
  NSlog(@"Called");
}
@end
  1. Zobacz delegowanie odbywa się poprzez protokół w cel c. myślę, że możesz zrozumieć jego składnię.

  2. W klasie songs tworzymy właściwość dla tego protokołu. zachowujemy Typ jako ID... ponieważ Typ nie jest znany w czasie kompilacji.

  3. W klasie songs po zakończeniu pobierania wywołujemy metodę protocol...

  4. W klasie głównej najpierw przyjmujemy składnię protokołu Klasa powyższe jest składnią tego

  5. The we instantiate the songs klasa

  6. Następnie przypisz Główny obiekt klasy (self) do delegata klasy songs

  7. Następnie musimy zastosować klasę Protokołu w .m przez dodanie nazwy metody z protokołu

  8. Więc od teraz zawsze, gdy Klasa songs wywoła metodę protokołu poprzez zmienną instancji delegata....out protocol method adoption on main class gets run

Wypróbuj ten kod, mam nadzieję, że pomoże...

Jeśli chcesz uzyskać więcej informacji na ten temat, google go jako delegate wzór projektu

Główną korzyścią jest Promuje luźno sprzężone programowanie...

 0
Author: Durai Amuthan.H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-19 15:45:39