Jak utworzyć delegatów w celu C?

głosy
683

Wiem, jak działają delegatów i wiem, jak mogę z nich korzystać.

Ale w jaki sposób je tworzyć?

Utwórz 09/03/2009 o 17:06
źródło użytkownik
W innych językach...                            


19 odpowiedzi

głosy
852

Celu -C pełnomocnik jest obiektem, który został przypisany do delegatewłaściwości innego obiektu. Aby utworzyć jedną, wystarczy zdefiniować klasy, która implementuje metody delegata Cię interesują, i oznaczyć tej klasy jako wdrożenie protokołu delegata.

Na przykład, załóżmy, że masz UIWebView. Jeśli chcesz, aby wdrożyć jej przedstawiciel w webViewDidStartLoad:sposób, można utworzyć klasę takiego:

@interface MyClass<UIWebViewDelegate>
// ...
@end

@implementation MyClass
- (void)webViewDidStartLoad:(UIWebView *)webView { 
    // ... 
}
@end

Następnie można utworzyć instancję MojaKlasa i przypisać go jako delegata widoku internetowej:

MyClass *instanceOfMyClass = [[MyClass alloc] init];
myWebView.delegate = instanceOfMyClass;

Na UIWebViewstronie, to prawdopodobnie ma kodu podobnego do tego, aby sprawdzić, czy delegat odpowiada na webViewDidStartLoad:wiadomości z wykorzystaniem respondsToSelector:i wysłać go w razie potrzeby.

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

Sama nieruchomość jest zwykle oświadczył delegat weak(w SM) lub assign(pre-ARC), aby uniknąć zatrzymywania pętle, ponieważ delegat obiektu często posiada wyraźne odniesienie do tego obiektu. (Na przykład, sterownik widok często delegat widzenia zawiera).

Dokonywanie Delegatów dla swoich klas

Definiowania własnych delegatów, musisz zadeklarować swoje metody gdzieś, jak to omówiono w firmy Apple Docs na protokołach . Zazwyczaj deklarują formalny protokół. Deklaracja, parafrazując od UIWebView.h, wyglądałby następująco:

@protocol UIWebViewDelegate <NSObject>
@optional
- (void)webViewDidStartLoad:(UIWebView *)webView;
// ... other methods here
@end

Jest to analogiczne do interfejsu lub abstrakcyjne klasy bazowej, ponieważ tworzy specjalny typ dla swojego delegata, UIWebViewDelegatew tym przypadku. Implementors Delegowanie musiałby przyjąć ten protokół:

@interface MyClass <UIWebViewDelegate>
// ...
@end

A następnie wdrożyć metody w protokole. Dla metod zadeklarowanych w protokole jako @optional(jak większość metod delegatów), trzeba skontaktować się z -respondsToSelector:przed wywołaniem konkretnej metody na nim.

Naming

Delegowanie metody są zwykle nazywane zaczynając od nazwy klasy delegujący i przejąć obiekt przekazał mu uprawnienia jako pierwszy parametr. Również często używają wola-, should- lub zlekceważyło formularz. Tak, webViewDidStartLoad:(pierwszy parametr jest widok WWW) zamiast loadStarted(biorąc żadnych parametrów) na przykład.

Optymalizacja prędkości

Zamiast sprawdzać, czy delegat odpowiada selektor każdym razem chcemy do wiadomości to, można buforować te informacje, gdy delegaci są ustawione. Jednym z bardzo czysty sposób, aby to zrobić jest użycie bitfield, co następuje:

@protocol SomethingDelegate <NSObject>
@optional
- (void)something:(id)something didFinishLoadingItem:(id)item;
- (void)something:(id)something didFailWithError:(NSError *)error;
@end

@interface Something : NSObject
@property (nonatomic, weak) id <SomethingDelegate> delegate;
@end

@implementation Something {
  struct {
    unsigned int didFinishLoadingItem:1;
    unsigned int didFailWithError:1;
  } delegateRespondsTo;
}
@synthesize delegate;

- (void)setDelegate:(id <SomethingDelegate>)aDelegate {
  if (delegate != aDelegate) {
    delegate = aDelegate;

    delegateRespondsTo.didFinishLoadingItem = [delegate respondsToSelector:@selector(something:didFinishLoadingItem:)];
    delegateRespondsTo.didFailWithError = [delegate respondsToSelector:@selector(something:didFailWithError:)];
  }
}
@end

Następnie w organizmie, możemy sprawdzić, że nasz delegat obsługuje wiadomości dostępu naszą delegateRespondsTostruct zamiast wysyłając -respondsToSelector:kółko.

nieformalne Delegaci

Przed istniały protokoły, było powszechne użycie kategorię na NSObjectuznaniu metod delegat może wdrożyć. Na przykład, CALayernadal to robi:

@interface NSObject(CALayerDelegate)
- (void)displayLayer:(CALayer *)layer;
// ... other methods here
@end

Wynika to przede wszystkim informuje kompilator, że każdy obiekt może realizować displayLayer:.

Można by wtedy użyć tego samego -respondsToSelector:podejścia, jak opisano powyżej, aby wywołać tę metodę. Delegaci po prostu wdrożyć tę metodę i przypisać delegatewłasność, i to (nie ma deklarując ty zgodne z protokołem). Metoda ta jest powszechna w bibliotekach Apple'a, ale nowy kod powinien użyć bardziej nowoczesne podejście protokołu powyżej, ponieważ takie podejście zanieczyszcza NSObject(co sprawia, autouzupełnianie mniej przydatne) i sprawia, że trudno dla kompilatora, aby ostrzec o literówek i podobnych błędów.

Odpowiedział 09/03/2009 o 17:16
źródło użytkownik

głosy
360

Zatwierdzona odpowiedź brzmi świetnie, ale jeśli szukasz 1 minutę odpowiedź spróbuj tego:

MyClass.h plik powinien wyglądać tak (dodaj linie delegata z komentarzami!)

#import <BlaClass/BlaClass.h>

@class MyClass;             //define class, so protocol can see MyClass
@protocol MyClassDelegate <NSObject>   //define delegate protocol
    - (void) myClassDelegateMethod: (MyClass *) sender;  //define delegate method to be implemented within another class
@end //end protocol

@interface MyClass : NSObject {
}
@property (nonatomic, weak) id <MyClassDelegate> delegate; //define MyClassDelegate as delegate

@end

Plik MyClass.m powinien wyglądać tak

#import "MyClass.h"
@implementation MyClass 
@synthesize delegate; //synthesise  MyClassDelegate delegate

- (void) myMethodToDoStuff {
    [self.delegate myClassDelegateMethod:self]; //this will call the method implemented in your other class    
}

@end

Aby użyć delegata w innej klasy (UIViewController nazywa MyVC w tym przypadku) MyVC.h:

#import "MyClass.h"
@interface MyVC:UIViewController <MyClassDelegate> { //make it a delegate for MyClassDelegate
}

MyVC.m:

myClass.delegate = self;          //set its delegate to self somewhere

Wdrożenie metody delegata

- (void) myClassDelegateMethod: (MyClass *) sender {
    NSLog(@"Delegates are great!");
}
Odpowiedział 30/09/2012 o 11:25
źródło użytkownik

głosy
18

W przypadku korzystania z protokołu formalną metodę tworzenia wsparcia delegata, odkryłem, że można zapewnić odpowiedni typ kontroli (aczkolwiek, wykonywania, nie skompilować czasu) dodając coś takiego:

if (![delegate conformsToProtocol:@protocol(MyDelegate)]) {
    [NSException raise:@"MyDelegate Exception"
                format:@"Parameter does not conform to MyDelegate protocol at line %d", (int)__LINE__];
}

w swoim delegatem accessor (setDelegate) kodu. Pomaga to zminimalizować błędy.

Odpowiedział 04/05/2010 o 21:42
źródło użytkownik

głosy
17

Może to jest bardziej wzdłuż linii, czego brakuje:

Jeżeli przyjeżdżasz z punktu widzenia C ++ jak delegaci trwa trochę przyzwyczaić - ale w zasadzie „po prostu działa”.

Jak to działa jest to, że można ustawić jakiś obiekt, który został zapisany jako delegat do NSWindow, ale twój obiekt ma tylko wdrożeń (metody) dla jednego lub kilku z wielu możliwych metod delegata. Więc coś się dzieje, i NSWindowchce zadzwonić do obiektu - po prostu używa Objective-C w respondsToSelectorsposób ustalić, czy obiekt chce tę metodę o nazwie, a następnie zwraca go. W ten sposób działa objective-c - metody są spojrzał na żądanie.

Jest całkowicie trywialne to zrobić z własnych obiektach, nie ma nic szczególnego dzieje, można na przykład mieć NSArrayz 27 obiektów, wszystkie rodzaje obiektów, tylko 18 niektóre z nich o metodę -(void)setToBue;Drugi 9 nie. Tak, aby zadzwonić setToBluena wszystkie 18, że trzeba to zrobić, coś takiego:

for (id anObject in myArray)
{
  if ([anObject respondsToSelector:@selector(@"setToBlue")])
     [anObject setToBlue]; 
}

Drugą rzeczą jest to, że delegaci nie są zachowane, więc zawsze trzeba ustawić delegata nilw swojej MyClass deallocmetodzie.

Odpowiedział 10/03/2009 o 01:18
źródło użytkownik

głosy
16

Proszę! sprawdź poniżej prosty krok po kroku, aby zrozumieć, w jaki sposób Delegaci działa w iOS.

Delegat w iOS

Stworzyłem dwa ViewControllers (do przesyłania danych z jednego do drugiego)

  1. FirstViewController realizacji pełnomocnik (który stanowi dane).
  2. SecondViewController oświadczam delegata (która będzie odbierać dane).
Odpowiedział 27/02/2013 o 13:21
źródło użytkownik

głosy
15

Jako dobrej praktyki zalecanej przez firmę Apple, to jest dobre dla delegata (który to protokół, z definicji), w celu dostosowania się do NSObjectprotokołu.

@protocol MyDelegate <NSObject>
    ...
@end

I stworzyć alternatywne metody w swoim delegatem (czyli metody, które niekoniecznie muszą być realizowane), można użyć @optionaladnotacji tak:

@protocol MyDelegate <NSObject>
    ...
    ...
      // Declaration for Methods that 'must' be implemented'
    ...
    ...
    @optional
    ...
      // Declaration for Methods that 'need not necessarily' be implemented by the class conforming to your delegate
    ...
@end

Więc przy użyciu metod, które zostały określone jako ty opcjonalne, trzeba (w swojej klasie) sprawdzić ze respondsToSelectorjeśli widok (który jest zgodny ze swoim delegatem) faktycznie realizowane Twoja opcja Metoda (-y) lub nie.

Odpowiedział 04/08/2013 o 09:39
źródło użytkownik

głosy
10

Myślę, że wszystkie te odpowiedzi uczynić wiele sensu po zrozumieniu delegatów. Osobiście przybył z krainy C / C ++, a wcześniej języków proceduralnych, takich jak Fortran etc więc tutaj jest moje 2 min wziąć na znalezienie podobnych analogów w C ++ paradygmatu.

Gdybym miał wyjaśnić delegatów do C ++ / programista Java Powiedziałbym

Jakie są delegaci? Są to wskaźniki do statycznych klas wewnątrz innej klasy. Po przypisaniu wskaźnika, można wywołać funkcji / metod w tej klasie. Stąd niektóre funkcje klasy są „delegowane” (w języku C ++ świecie - wskaźnik do wskaźnika przez obiekt klasy) do innej klasy.

Jakie są protokoły? Koncepcyjnie służy jako podobnemu celowi co do nagłówka pliku klasy jesteś nadającego jako klasa delegata. Protokół jest wyraźny sposób definiowania jakie metody musi być realizowane w klasie, który znajduje się wskaźnik został ustawiony jako delegat w klasie.

Jak mogę zrobić coś podobnego w C ++? Jeśli próbował to zrobić w C ++, byś poprzez zdefiniowanie wskaźników do klasy (obiektów) w definicji klasy, a następnie okablowanie je do innych klas, które zapewnią dodatkowe funkcje jak delegatów do swojej klasy bazowej. Ale to okablowanie musi być maitained w kodzie i będzie niezdarny i podatne na błędy. Cel C prostu zakłada, że ​​programiści nie są najlepsze na utrzymanie tego decipline i zapewnia ograniczeń kompilatora egzekwować czystą realizację.

Odpowiedział 19/06/2013 o 11:34
źródło użytkownik

głosy
9

wersja Swift

Delegat jest właśnie klasa, która wykonuje pracę dla innej klasy. Przeczytaj poniższy kod nieco głupie (ale miejmy nadzieję pouczające) Playground przykład, który pokazuje, w jaki sposób odbywa się to w Swift.

// A protocol is just a list of methods (and/or properties) that must
// be used by any class that adopts the protocol.
protocol OlderSiblingDelegate: class {
    // This protocol only defines one required method
    func getYourNiceOlderSiblingAGlassOfWater() -> String
}

class BossyBigBrother {

    // The delegate is the BossyBigBrother's slave. This position can 
    // be assigned later to whoever is available (and conforms to the 
    // protocol).
    weak var delegate: OlderSiblingDelegate?

    func tellSomebodyToGetMeSomeWater() -> String? {
        // The delegate is optional because there might not be anyone
        // nearby to boss around.
        return delegate?.getYourNiceOlderSiblingAGlassOfWater()
    }
}

// PoorLittleSister conforms to the OlderSiblingDelegate protocol
class PoorLittleSister: OlderSiblingDelegate {

    // This method is repquired by the protocol, but the protocol said
    // nothing about how it needs to be implemented.
    func getYourNiceOlderSiblingAGlassOfWater() -> String {
        return "Go get it yourself!"
    }

}

// initialize the classes
let bigBro = BossyBigBrother()
let lilSis = PoorLittleSister()

// Set the delegate 
// bigBro could boss around anyone who conforms to the 
// OlderSiblingDelegate protocol, but since lilSis is here, 
// she is the unlucky choice.
bigBro.delegate = lilSis

// Because the delegate is set, there is a class to do bigBro's work for him.
// bigBro tells lilSis to get him some water.
if let replyFromLilSis = bigBro.tellSomebodyToGetMeSomeWater() {
    print(replyFromLilSis) // "Go get it yourself!"
}

W praktyce, delegaci są często używane w następujących sytuacjach

  1. Kiedy klasa musi komunikować pewne informacje do innej klasy
  2. Kiedy klasa chce zezwolić innej klasy, aby go dostosować

Klasy nie trzeba nic wiedzieć o sobie nawzajem z wyprzedzeniem, z wyjątkiem, że klasa delegat jest zgodny z wymaganym protokołem.

Gorąco polecam przeczytaniu poniższego dwa artykuły. Pomogli mi zrozumieć delegatów nawet lepiej niż dokumentacja zrobił.

Odpowiedział 05/11/2015 o 17:11
źródło użytkownik

głosy
8

powiedzmy, że masz klasę, że opracowany i chcą zadeklarować właściwość delegata, aby móc powiadomić go, gdy pewne zdarzenie:

@class myClass;

@protocol myClassDelegate <NSObject>

-(void)myClass:(MyClass*)myObject requiredEventHandlerWithParameter:(ParamType*)param;

@optional
-(void)myClass:(MyClass*)myObject optionalEventHandlerWithParameter:(ParamType*)param;

@end


@interface MyClass : NSObject

@property(nonatomic,weak)id< MyClassDelegate> delegate;

@end

więc zadeklarować protokół w MyClasspliku nagłówka (lub oddzielny plik nagłówka) i zadeklarować wymagane / opcja obsługi zdarzeń, że delegat muszą / powinny wdrożyć, a następnie zadeklarować obiektu MyClasstypu ( id< MyClassDelegate>), które oznaczają wszelkie obiektywne klasy C, który jest zgodny protokół MyClassDelegate, można zauważyć, że nieruchomość delegat jest zadeklarowana jako słaby, to jest bardzo ważne, aby zapobiec zachować cykl (najczęściej delegat zachowuje MyClassinstancji więc jeśli zadeklarowana jako delegata zatrzymywania, oboje zachowują się wzajemnie i nie z nich nigdy nie będzie zwolniony).

można zauważyć również, że metody protokołu przekazuje MyClassinstancji delegata jako parametr, to jest najlepsze praktyki w przypadku, gdy delegat chce zadzwonić kilka metod na MyClassprzykład, a także pomaga, gdy delegat deklaruje się jako MyClassDelegatedo wielu MyClassprzypadkach, jak w przypadku wielu UITableView'sprzypadki, w twojej ViewControlleri deklaruje się jako UITableViewDelegatedo nich wszystkich.

i wewnątrz MyClasspowiadomić delegata ze zgłoszonych zdarzeń w następujący sposób:

if([_delegate respondsToSelector:@selector(myClass: requiredEventHandlerWithParameter:)])
{
     [_delegate myClass:self requiredEventHandlerWithParameter:(ParamType*)param];
}

najpierw sprawdzić, czy delegat odpowiada metodzie protokół, który masz zamiar zadzwonić w przypadku, gdy delegat nie implementuje go, a następnie aplikacja awarii (nawet jeśli wymagana jest metoda Protocol).

Odpowiedział 08/04/2015 o 13:24
źródło użytkownik

głosy
8

Ok, to nie jest to odpowiedź na pytanie, ale jeśli patrząc jak zrobić własny delegata może coś znacznie prostszy mógłby być lepszym rozwiązaniem dla Ciebie.

I trudno realizować moje delegatów bo rzadko potrzebne. Mogę mieć tylko jednego delegata dla obiektu delegowanego. Więc jeśli chcesz, aby Twój delegat na jeden sposób komunikacji / przekazywanie danych niż jesteś dużo lepszy z powiadomień.

NSNotification może przekazać obiekty do więcej niż jednego odbiorcy i jest bardzo łatwy w użyciu. Działa to tak:

Plik MyClass.m powinien wyglądać tak

#import "MyClass.h"
@implementation MyClass 

- (void) myMethodToDoStuff {
//this will post a notification with myClassData (NSArray in this case)  in its userInfo dict and self as an object
[[NSNotificationCenter defaultCenter] postNotificationName:@"myClassUpdatedData"
                                                    object:self
                                                  userInfo:[NSDictionary dictionaryWithObject:selectedLocation[@"myClassData"] forKey:@"myClassData"]];
}
@end

Aby korzystać z powiadomienia w kolejnych klasach: Dodaj klasę jako obserwator:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(otherClassUpdatedItsData:) name:@"myClassUpdatedData" object:nil];

Wdrożenie selektora:

- (void) otherClassUpdatedItsData:(NSNotification *)note {
    NSLog(@"*** Other class updated its data ***");
    MyClass *otherClass = [note object];  //the object itself, you can call back any selector if you want
    NSArray *otherClassData = [note userInfo][@"myClassData"]; //get myClass data object and do whatever you want with it
}

Nie zapomnij usunąć klasę jako obserwator, jeżeli

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
Odpowiedział 17/07/2013 o 05:58
źródło użytkownik

głosy
6

Oto prosty sposób na tworzenie delegatów

Tworzenie protokołu w pliku .h. Upewnij się, że jest zdefiniowany przed użyciem protokołu @class następnie imię UIViewController< As the protocol I am going to use is UIViewController class>.

Krok 1: Tworzenie nowej klasy protokołu o nazwie „YourViewController”, który będzie podklasą klasy UIViewController i przypisać tej klasy do drugiej ViewController.

Krok: 2: Idź do „YourViewController” pliku i modyfikować go jak poniżej:

#import <UIKit/UIkit.h>
@class YourViewController;

@protocol YourViewController Delegate <NSObject>

 @optional
-(void)defineDelegateMethodName: (YourViewController *) controller;

@required
-(BOOL)delegateMethodReturningBool: (YourViewController *) controller;

  @end
  @interface YourViewController : UIViewController

  //Since the property for the protocol could be of any class, then it will be marked as a type of id.

  @property (nonatomic, weak) id< YourViewController Delegate> delegate;

@end

Metody zdefiniowane w zachowaniu Protokół ten może być kontrolowany z @optional i @required jako część definicji protokołu.

Krok 3: Wykonanie Delegata

    #import "delegate.h"

   @interface YourDelegateUser ()
     <YourViewControllerDelegate>
   @end

   @implementation YourDelegateUser

   - (void) variousFoo {
      YourViewController *controller = [[YourViewController alloc] init];
      controller.delegate = self;
   }

   -(void)defineDelegateMethodName: (YourViewController *) controller {
      // handle the delegate being called here
   }

   -(BOOL)delegateMethodReturningBool: (YourViewController *) controller {
      // handle the delegate being called here
      return YES;
   }

   @end

// sprawdzenie, czy metoda została zdefiniowana przed nazwać

 - (void) someMethodToCallDelegate {
     if ([[self delegate] respondsToSelector:@selector(defineDelegateMethodName:)]) {
           [self.delegate delegateMethodName:self]; 
     }
  }
Odpowiedział 29/09/2015 o 09:23
źródło użytkownik

głosy
5

Aby utworzyć własny delegata, najpierw trzeba utworzyć protokół i deklarują niezbędnych metod, bez realizacji. A następnie wdrożyć ten protokół w swojej klasie nagłówka, w którym chcesz, aby wdrożyć metody delegata lub delegata.

Protokół musi zostać uznane, jak poniżej:

@protocol ServiceResponceDelegate <NSObject>

- (void) serviceDidFailWithRequestType:(NSString*)error;
- (void) serviceDidFinishedSucessfully:(NSString*)success;

@end

Jest to usługa, gdzie niektóre klasy zadanie powinno być zrobione. To pokazuje, jak zdefiniować delegata i jak ustawić delegata. W klasie realizacji po zakończeniu zadania delegata za metody są nazywane.

@interface ServiceClass : NSObject
{
id <ServiceResponceDelegate> _delegate;
}

- (void) setDelegate:(id)delegate;
- (void) someTask;

@end

@implementation ServiceClass

- (void) setDelegate:(id)delegate
{
_delegate = delegate;
}

- (void) someTask
{
/*

   perform task

*/
if (!success)
{
[_delegate serviceDidFailWithRequestType:@”task failed”];
}
else
{
[_delegate serviceDidFinishedSucessfully:@”task success”];
}
}
@end

Jest to główna klasa widok skąd klasa usługa nazywa się poprzez ustawienie delegata do siebie. A także protokół jest realizowany w klasie nagłówka.

@interface viewController: UIViewController <ServiceResponceDelegate>
{
ServiceClass* _service;
}

- (void) go;

@end

@implementation viewController

//
//some methods
//

- (void) go
{
_service = [[ServiceClass alloc] init];
[_service setDelegate:self];
[_service someTask];
}

To wszystko, a także poprzez wdrażanie metod delegata w tej klasie, sterowanie wróci po operacji / zadanie zostało wykonane.

Odpowiedział 03/08/2015 o 04:47
źródło użytkownik

głosy
1

Uwaga: jest to Swiftwersja jak stworzyć delegate.

Więc, jakie są delegaci? ... w rozwoju oprogramowania, istnieje ogólne wielokrotnego architektury rozwiązania, które pomogą rozwiązać problemy występujące powszechnie w danym kontekście, te „szablony”, że tak powiem, najlepiej znany jako wzorców projektowych. Delegaci są wzorzec projektowy, który umożliwia jeden obiekt do wysyłania wiadomości do innego obiektu, gdy określone zdarzenie dzieje. Wyobraź sobie obiekt dzwoni obiektu B, aby wykonać działanie. Gdy akcja się zakończy, przedmiot A powinien wiedzieć, że B zakończył zadanie i podjąć niezbędne działania, można to osiągnąć za pomocą delegatów!

Dla lepszego wyjaśnienia, mam zamiar pokazać, jak utworzyć własny delegata, który przekazuje dane między klasami, z Swift w prostej aplikacji uruchomić pobierając lub sklonowanie tego projektu rozrusznika i uruchomić go!

Można zobaczyć aplikację z dwóch klas, ViewController Aa ViewController B. B ma dwa widoki, które w sposób ciągły zmienia kolor tła ViewController, nic skomplikowanego prawa? dobrze teraz pomyślmy w łatwy sposób również zmienić kolor tła klasy A gdy poglądy na klasy B są na podsłuchu.

Problemem jest to, że widoki są częścią klasy B i nie mają pojęcia o klasie A, więc musimy znaleźć sposób komunikowania się pomiędzy tych dwóch klas, i to, gdzie delegacja świeci. I podzielić wdrożenie na 6 etapów, dzięki czemu można używać tego jako ściągawki, gdy jest to potrzebne.

Krok 1: Spójrz na etapie znaku Pragma 1 w pliku ClassBVC i dodać

//MARK: step 1 Add Protocol here.
protocol ClassBVCDelegate: class {
func changeBackgroundColor(_ color: UIColor?)
}

Pierwszym krokiem jest stworzenie protocol, w tym przypadku, będziemy tworzyć protokół w klasie B, wewnątrz protokołu można utworzyć dowolną liczbę funkcji, które mają być oparte na wymaganiach implementacji. W tym przypadku mamy tylko jedną prostą funkcję, która przyjmuje opcjonalny UIColorjako argument. Jest to dobra praktyka, aby wymienić swoje protokoły dodanie słowa delegatena końcu nazwy klasy, w tym przypadku ClassBVCDelegate.

krok 2: Spójrz na etapie 2 w znaku Pragma ClassVBCi dodać

//MARK: step 2 Create a delegate property here.
weak var delegate: ClassBVCDelegate?

Tutaj po prostu utworzyć właściwość delegata dla klasy, ta właściwość musi przyjąć protocolrodzaj, a powinno być dobrowolne. Ponadto, należy dodać słabą słowa kluczowego przed nieruchomości, aby uniknąć zatrzymywania cykli i potencjalnych wycieków pamięci, jeśli nie wiesz co to znaczy nie martw się na razie, tylko pamiętaj, aby dodać słowo kluczowe.

krok 3: Spójrz na etapie znaku Pragma 3 wewnątrz handleTap methodw ClassBVCi dodać

//MARK: step 3 Add the delegate method call here.
delegate?.changeBackgroundColor(tapGesture.view?.backgroundColor)

Jedną z rzeczy, które powinieneś wiedzieć, uruchom aplikację i stuknij w każdym razie, nie będzie widać żadnych nowych zachowań i to jest prawidłowe, ale tym, co chcę podkreślić to, że aplikacja nie jest upaść, gdy delegat nazywa, i to dlatego tworzymy go jako opcjonalny wartości i dlatego nie padnie nawet delegowany jeszcze nie istnieje. Załóżmy teraz przejść do ClassAVCpliku i zrobić to, delegowany.

Krok 4: Spójrz na etapie znaku Pragma 4 wewnątrz metody handleTap w ClassAVCi dodać ten obok typu klasy jak ten.

//MARK: step 4 conform the protocol here.
class ClassAVC: UIViewController, ClassBVCDelegate {
}

Teraz ClassAVC przyjął ClassBVCDelegateprotokół, można zobaczyć, że kompilator daje błąd, który mówi „Typ„ClassAVC nie jest zgodny z protokołem «ClassBVCDelegate», a to oznacza tylko, że nie użyto metody protokołu jednak wyobrazić, że gdy klasa a przyjmuje protokół jest jak podpisanie umowy z klasy B i ten kontrakt mówi „Każda klasa przyjęcie mnie MUSI wykorzystać moje funkcje!”

Szybka uwaga: Jeśli pochodzą z Objective-Ctłem jesteś prawdopodobnie myśli, że można również zamknąć ten błąd wynika to metoda opcjonalna, ale dla mojego zaskoczenia i prawdopodobnie twój, Swiftjęzyk nie obsługuje opcjonalne protocols, jeśli chcesz to zrobić można utworzyć rozszerzenie dla twojego protocollub użyć @objc słowa kluczowego w swojej protocolrealizacji.

Osobiście Jeśli mam stworzyć protokół z różnych opcjonalnych metod wolałbym aby podzielić go na inny protocols, w ten sposób będę podążać pojęcie daje pojedynczą odpowiedzialność moich przedmiotów, ale mogą się różnić w zależności od konkretnej implementacji.

tutaj jest dobry artykuł na temat metod opcjonalnych.

Krok 5: Spójrz na etapie znaku Pragma 5 wewnątrz Przygotowanie do sposobu Segue i dodać

//MARK: step 5 create a reference of Class B and bind them through the `prepareforsegue` method.
if let nav = segue.destination as? UINavigationController, let classBVC = nav.topViewController as? ClassBVC {
classBVC.delegate = self
}

Tu są tylko tworzenie instancji ClassBVCi przypisz jej delegata do siebie, ale to, co jest samo tutaj? dobrze, to samo ClassAVC, które zostało przekazane!

Krok 6: Wreszcie, poszukaj kroku pragma 6 ClassAVCi użyjmy funkcji protocol, zacznij wpisywać funkcjono changeBackgroundColor i widać, że jest to auto ukończenie go dla Ciebie. Można dodać dowolną implementację wewnątrz niego, w tym przykładzie, będziemy po prostu zmienić kolor tła, dodać to.

//MARK: step 6 finally use the method of the contract
func changeBackgroundColor(_ color: UIColor?) {
view.backgroundColor = color
}

Teraz uruchom aplikację!

Delegatessą wszędzie i prawdopodobnie ich używać nawet bez zawiadomienia, jeśli utworzyć tablevieww przeszłości używane delegacji, wiele klas UIKITprac wokół nich i wielu innych frameworks, oni też rozwiązać te główne problemy.

  • Unikać szczelne łączenie obiektów.
  • Modyfikować zachowanie i wygląd bez konieczności podklasy obiektów.
  • Ce zadania należy obchodzić się do dowolnej obiektu.

Gratulacje, właśnie wdrożenie niestandardowych delegata, wiem, że jesteś prawdopodobnie myśli, tyle kłopotów tylko do tego? dobrze, delegacja jest bardzo ważne, aby zrozumieć wzorzec projektowy, jeśli chcesz, aby stać się iOSdeweloperem i zawsze pamiętać, że mają one związek jeden do jednego między obiektami.

Można zobaczyć oryginalne samouczek tutaj

Odpowiedział 26/04/2017 o 05:27
źródło użytkownik

głosy
1

ViewController.h

@protocol NameDelegate <NSObject>

-(void)delegateMEthod: (ArgType) arg;

@end

@property id <NameDelegate> delegate;

ViewController.m

[self.delegate delegateMEthod: argument];

MainViewController.m

ViewController viewController = [ViewController new];
viewController.delegate = self;

Metoda:

-(void)delegateMEthod: (ArgType) arg{
}
Odpowiedział 19/12/2016 o 04:14
źródło użytkownik

głosy
0

Odpowiedź została faktycznie odpowiedział, ale chciałbym, aby dać „Ściągawka” dla tworzenia delegata:

DELEGATE SCRIPT

CLASS A - Where delegate is calling function

@protocol <#Protocol Name#> <NSObject>

-(void)delegateMethod;

@end

@interface <#Some ViewController#> : <#UIViewController#> 

@property (nonatomic, assign) id <<#Protocol Name#>> delegate;

@end


@implementation <#Some ViewController#> 

-(void)someMethod {
    [self.delegate methodName];
}

@end




CLASS B - Where delegate is called 

@interface <#Other ViewController#> (<#Delegate Name#>) {}
@end

@implementation <#Other ViewController#> 

-(void)otherMethod {
    CLASSA *classA = [[CLASSA alloc] init];

    [classA setDelegate:self];
}

-delegateMethod() {

}

@end
Odpowiedział 16/03/2018 o 04:40
źródło użytkownik

głosy
0

Zacznijmy od przykładu, jeśli kupujemy produkt online, to przechodzi przez proces podobny wysyłki / dostawy obsługiwane przez różne teams.So jeśli przesyłka zostanie zakończona, wysyłka zespół powinien powiadomić zespół dostawy i powinien to być jeden do jednego komunikacji jako przekazu informacyjnego to byłoby napowietrznych do innych osób / sprzedawca może chcieć przekazać tę informację tylko do potrzebnych ludzi.

Więc jeśli myślimy w kategoriach naszej aplikacji, zdarzenie może być zamówienie online i różne zespoły mogą być jak wielu widoków.

Oto kod rozważyć ShippingView jako zespół Shipping & DeliveryView jako zespół dostawy:

//Declare the protocol with functions having info which needs to be communicated
protocol ShippingDelegate : class {
    func productShipped(productID : String)
}
//shippingView which shows shipping status of products
class ShippingView : UIView
{

    weak var delegate:ShippingDelegate?
    var productID : String

    @IBAction func checkShippingStatus(sender: UIButton)
    {
        // if product is shipped
        delegate?.productShipped(productID: productID)
    }
}
//Delivery view which shows delivery status & tracking info
class DeliveryView: UIView,ShippingDelegate
{
    func productShipped(productID : String)
    {
        // update status on view & perform delivery
    }
}

//Main page on app which has both views & shows updated info on product whole status
class ProductViewController : UIViewController
{
    var shippingView : ShippingView
    var deliveryView : DeliveryView

    override func viewDidLoad() {
        super.viewDidLoad()
        // as we want to update shipping info on delivery view, so assign delegate to delivery object
        // whenever shipping status gets updated it will call productShipped method in DeliveryView & update UI.
        shippingView.delegate = deliveryView
        //
    }
}
Odpowiedział 14/07/2017 o 10:14
źródło użytkownik

głosy
0

Z mojego punktu widzenia utworzyć oddzielną klasę dla tej metody delegata i można użyć tam, gdzie chcesz.

w niestandardowej DropDownClass.h

typedef enum
{
 DDSTATE,
 DDCITY
}DropDownType;

@protocol DropDownListDelegate <NSObject>
@required
- (void)dropDownDidSelectItemWithString:(NSString*)itemString     DropDownType:(DropDownType)dropDownType;
@end
@interface DropDownViewController : UIViewController
{
 BOOL isFiltered;
}
@property (nonatomic, assign) DropDownType dropDownType;
@property (weak) id <DropDownListDelegate> delegate;
@property (strong, nonatomic) NSMutableArray *array1DropDown;
@property (strong, nonatomic) NSMutableArray *array2DropDown;

po tym pliku in.m utworzyć tablicę z obiektami,

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
CGFloat rowHeight = 44.0f;
return rowHeight;
}

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return isFiltered?[self.array1DropDown count]:[self.array2DropDown count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"TableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}

if (self.delegate) {
    if (self.dropDownType == DDCITY) {
        cell.textLabel.text = [self.array1DropDown objectAtIndex:indexPath.row];
    }
    else if (self.dropDownType == DDSTATE) {
        cell.textLabel.text = [self.array2DropDown objectAtIndex:indexPath.row];
    }
}
return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
 [self dismissViewControllerAnimated:YES completion:^{
    if(self.delegate){
        if(self.dropDownType == DDCITY){
            [self.delegate dropDownDidSelectItemWithString:[self.array1DropDown objectAtIndex:indexPath.row] DropDownType:self.dropDownType];
        }
        else if (self.dropDownType == DDSTATE) {
            [self.delegate dropDownDidSelectItemWithString:[self.array2DropDown objectAtIndex:indexPath.row] DropDownType:self.dropDownType];
        }
    }
}];
}

Tutaj wszyscy są ustawione na niestandardowe delegata class.after że można wykorzystać tę metodę delegata, gdzie przykładem want.for ...

w moim innym importu viewcontroller po tym

utworzyć działanie na wywołanie metody delegata tak

- (IBAction)dropDownBtn1Action:(id)sender {
DropDownViewController *vehicleModelDropView = [[DropDownViewController alloc]init];
vehicleModelDropView.dropDownType = DDCITY;
vehicleModelDropView.delegate = self;
[self presentViewController:vehicleModelDropView animated:YES completion:nil];
}

Po tej metody wywołanie delegata takich jak to

- (void)dropDownDidSelectItemWithString:(NSString *)itemString DropDownType:(DropDownType)dropDownType {
switch (dropDownType) {
    case DDCITY:{
        if(itemString.length > 0){
            //Here i am printing the selected row
            [self.dropDownBtn1 setTitle:itemString forState:UIControlStateNormal];
        }
    }
        break;
    case DDSTATE: {
        //Here i am printing the selected row
        [self.dropDownBtn2 setTitle:itemString forState:UIControlStateNormal];
    }

    default:
        break;
}
}
Odpowiedział 08/02/2017 o 09:30
źródło użytkownik

głosy
0
//1.
//Custom delegate 
@protocol TB_RemovedUserCellTag <NSObject>

-(void)didRemoveCellWithTag:(NSInteger)tag;

@end

//2.
//Create a weak reference in a class where you declared the delegate
@property(weak,nonatomic)id <TB_RemovedUserCellTag> removedCellTagDelegate;

//3. 
// use it in the class
  [self.removedCellTagDelegate didRemoveCellWithTag:self.tag];

//4. import the header file in the class where you want to conform to the protocol
@interface MyClassUsesDelegate ()<TB_RemovedUserCellTag>

@end

// 5. Realizacji sposobu w .m klasy - (void) didRemoveCellWithTag (NSInteger) znacznika {NSLog @ ( "znacznika% D", znacznik);

}

Odpowiedział 02/01/2017 o 16:31
źródło użytkownik

głosy
0

Delegować: - Tworzenie

@protocol addToCartDelegate <NSObject>

-(void)addToCartAction:(ItemsModel *)itemsModel isAdded:(BOOL)added;

@end

Wysyłanie i należy przypisać delegata aby wysyłasz dane

[self.delegate addToCartAction:itemsModel isAdded:YES];
Odpowiedział 08/12/2016 o 10:50
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more