Tudom, hogy a küldöttek működik, és tudom, hogyan tudom használni őket.
De hogyan kell létrehozni őket?
Tudom, hogy a küldöttek működik, és tudom, hogyan tudom használni őket.
De hogyan kell létrehozni őket?
Egy Objective-C küldötte olyan objektum, amely hozzá van rendelve a delegatetulajdonság egy másik tárgyat. Ahhoz, hogy hozzon létre egyet, egyszerűen meg egy osztályt, amely megvalósítja a küldött módszer az Önt érdeklő, és jelölje meg, hogy az osztály a végrehajtási megbízottja protokollt.
Tegyük fel például, hogy van egy UIWebView. Ha azt szeretné, hogy hajtsák végre a felhatalmazotti webViewDidStartLoad:módszer, akkor hozzon létre egy osztályt, mint ez:
@interface MyClass<UIWebViewDelegate>
// ...
@end
@implementation MyClass
- (void)webViewDidStartLoad:(UIWebView *)webView {
// ...
}
@end
Akkor készíthet egy példánya MyClass és jelölje ki azt az internetes nézet megbízottja:
MyClass *instanceOfMyClass = [[MyClass alloc] init];
myWebView.delegate = instanceOfMyClass;
Az UIWebViewoldalon, valószínűleg hasonló kód ezt látni, ha a küldött reagál a webViewDidStartLoad:üzenetet respondsToSelector:, és küldje el, ha szükséges.
if([self.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
[self.delegate webViewDidStartLoad:self];
}
A küldött tulajdonság önmagában jellemzően deklarált weak(ARC), vagy assign(pre-ARC), hogy elkerüljék megtartja hurkok, mivel a küldötte egy tárgy gyakran tart egy erős utalás, hogy a tárgyat. (Például egy nézetvezérlőben gyakran a képviselője a céllal, hogy tartalmaz.)
Hogy meghatározza a saját átruházza, akkor meg kell, hogy állapítsa meg a módszereiket valahol, ahogy azt a Apple Docs jegyzőkönyvei . Általában nyilvánítja a hivatalos protokoll. A nyilatkozatot, körülírással származó UIWebView.h, így nézne ki:
@protocol UIWebViewDelegate <NSObject>
@optional
- (void)webViewDidStartLoad:(UIWebView *)webView;
// ... other methods here
@end
Ez analóg a felület vagy absztrakt alap osztály, hiszen létrehoz egy speciális, az Ön megbízottja, UIWebViewDelegateebben az esetben. Küldött implementors volna elfogadni ezt a protokollt:
@interface MyClass <UIWebViewDelegate>
// ...
@end
És akkor végre a módszerek a protokoll. Mert metódusnak a protokoll @optional(mint a legtöbb küldött módszerek), akkor ellenőrizni kell a -respondsToSelector:hívás előtt egy bizonyos módszer rajta.
Küldötte módszerek jellemzően megnevezett kiindulási az átruházó osztály nevét, és megteszi a felhatalmazó tárgyat, mint az első paraméter. Azt is gyakran használják a készségüket, should- vagy did- formában. Tehát, webViewDidStartLoad:(első paraméter az internetes nézet) helyett loadStarted(figyelembe paraméterek nélkül) pl.
Ahelyett, hogy annak ellenőrzése, hogy egy meghatalmazott válaszol egy választó minden alkalommal szeretnénk az üzenethez, akkor cache az adatokat, ha a küldöttek vannak beállítva. Egy nagyon tiszta módja ennek az, hogy egy bitmező, az alábbiak szerint:
@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
Ezután a test, tudjuk ellenőrizni, hogy a küldött üzenetekkel elérésével a delegateRespondsTostruct, ahelyett küldött -respondsToSelector:újra és újra.
Mielőtt protokollok létezett, ez volt a közös, hogy egy kategória a NSObjectnyilatkozni módszerek küldöttje lehet végrehajtani. Például CALayermég mindig ezt csinálja:
@interface NSObject(CALayerDelegate)
- (void)displayLayer:(CALayer *)layer;
// ... other methods here
@end
Ez lényegében azt mondja a fordítónak, hogy bármilyen tárgy lehet végrehajtani displayLayer:.
Te aztán használja ugyanazt a -respondsToSelector:megközelítést a fent leírt módon hívja ezt a módszert. A küldöttek egyszerűen végrehajtja ezt a módszert, és rendelje hozzá a delegatetulajdon, és ennyi (nincs kijelentve akkor felelnek meg a protokoll). Ez a módszer elterjedt az Apple könyvtárak, de az új kódot kell használni a modern protokoll megközelítés felett, mivel ez a megközelítés szennyezi NSObject(ami autocomplete kevésbé hasznos), és megnehezíti a fordító, hogy figyelmeztessen a helyesírási és a hasonló hibákat.
A jóváhagyott válasz jó, de ha keres egy 1 perces válasz próbáld ezt:
MyClass.h fájlt kell kinéznie (add küldött vonalak megjegyzéseket!)
#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
MyClass.m fájlt kell kinéznie
#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
Ahhoz, hogy a küldött egy másik osztályba (UIViewController úgynevezett MyVC ebben az esetben) 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
Végre küldötte módszer
- (void) myClassDelegateMethod: (MyClass *) sender {
NSLog(@"Delegates are great!");
}
Amikor a hivatalos protokoll módszer létrehozására küldött támogatást, azt találtuk, hogy biztosítani tudja a megfelelő típusú ellenőrző (jóllehet, játékidő nem fordul idő) hozzáadásával valami ilyesmit:
if (![delegate conformsToProtocol:@protocol(MyDelegate)]) {
[NSException raise:@"MyDelegate Exception"
format:@"Parameter does not conform to MyDelegate protocol at line %d", (int)__LINE__];
}
a delegált tartozék (setDelegate) kódot. Ez minimálisra csökkenti a hibákat.
Lehet, hogy ez több mentén, mit hiányoznak:
Ha jön egy C ++ mint szempontból küldöttek vesz egy kicsit szokni kell - de alapvetően „ők csak a munka.”
Ez úgy működik, hogy hozzanak néhány tárgyat, amit írtam, a küldöttet NSWindow, de a tárgy csak megvalósítások (módszerek) egy vagy néhány a sok lehetőség közül delegált módszerekkel. Tehát valami történik, és NSWindowazt akarja, hogy hívja fel a tárgyat - ez csak használ Objective-C respondsToSelectormeghatározására szolgáló módszer, ha a tárgy akarja, hogy nevezett módszert, majd hívja. Így az Objective C-munkák - módszerek felnézett igény.
Ez teljesen triviális, hogy ezt a saját tárgyak, nincs semmi különleges folyik, akkor például van egy NSArray27 tárgy, minden féle tárgyak, mindössze 18 némelyikük amelynek az eljárás -(void)setToBue;a többi 9 nem. Tehát, hogy hívja setToBluefel az összes 18, hogy szüksége van rá kész, valahogy így:
for (id anObject in myArray)
{
if ([anObject respondsToSelector:@selector(@"setToBlue")])
[anObject setToBlue];
}
A másik dolog az, hogy a küldöttek nem tartják meg, így mindig be kell állítani a küldöttet nila MyClass deallocmódszerrel.
Kérem! ellenőrizze az alábbi egyszerű, lépésről lépésre bemutató megérteni, hogyan működik küldöttek iOS.
Létrehoztam két ViewControllers (adatküldés az egyikből a másikba)
Mint egy jó gyakorlat az Apple által ajánlott, ez jó a küldöttet (ami egy olyan protokoll, definíció szerint), hogy megfeleljenek a NSObjectprotokollt.
@protocol MyDelegate <NSObject>
...
@end
& Létrehozni választható módszerek belül a felhatalmazott (azaz olyan módszerekkel, amelyek nem szükségszerűen kell végrehajtani), akkor a @optionalkommentár, mint ez:
@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
Tehát amikor módszerekkel, hogy a megadott opcionális, meg kell (az osztályban), ellenőrizze respondsToSelector, ha a néző (amely megfelel az Ön megbízottja) a ténylegesen végrehajtott a választható mód (ok), vagy sem.
Azt hiszem, ezek a válaszok, hogy sok értelme van, ha érti küldötteket. Személy szerint én érkezett a föld C / C ++, és mielőtt az eljárási nyelvek, mint a Fortran stb, így itt van a 2 perc, hogy találjanak hasonló analógok C ++ paradigma.
Ha én magyarázni küldöttek egy C ++ / Java programozó azt mondanám
Mik küldöttek? Ezek statikus mutatókat osztályokban másik osztályba. Miután kiosztotta a mutató, akkor hívja funkciók / módszerek ebben az osztályban. Ezért bizonyos funkciók az osztály a „felhatalmazáson alapuló” (C ++ világban - mutatót egy objektum osztály pointer) egy másik osztályba.
Mik protokollok? Fogalmi szolgál hasonló célra, hogy a header fájlt az osztály Ön rendel hozzá küldöttnek osztályban. A jegyzőkönyv egy explicit módon határozhatók milyen módszerekkel kell végrehajtani az osztályban, aki mutatót hoztak küldöttnek egy osztályon belül.
Hogyan lehet valami hasonlót csinálni C ++? Ha megpróbálta ezt a C ++, akkor meghatározásával mutatókat osztályok (objektum) az osztály definíciója, majd bekötése őket, hogy más osztályokba, amely további funkciók, mint a küldötteket, hogy a szülő osztály. De ez a vezetékeket kell engedünk a kódot, és lesz ügyetlen és hibára hajlamos. Objective C csak feltételezi, hogy a programozók nem a legjobb, hogy fenntartsák ezt a decipline és biztosítja fordító korlátozásokat érvényesíteni tiszta végrehajtásához.
Egy küldött csak egy osztály, amely munkát végez egy másik osztályba. Olvassa el az alábbi kódot egy kissé buta (de remélhetőleg tanulságos) Játszótér példa, amely azt mutatja, hogy ez hogyan történik 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!"
}
A gyakorlatban küldöttek gyakran használják az alábbi esetekben
Az osztályok nem kell tudni semmit egymást előre, kivéve, hogy a megbízott osztály megfelel a kívánt protokollt.
Én nagyon ajánlom a következő két cikket. Segítettek megérteni küldöttek még jobb, mint a dokumentáció tette.
tegyük fel, hogy egy osztályt, hogy a fejlett és akar nyilatkozni küldöttje tulajdonság, hogy képes legyen értesítik, ha valamilyen esemény történik:
@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
így nyilvánítja protokoll MyClassheader fájlt (vagy egy külön header fájl), és állapítsa meg a szükséges / nem kötelező eseménykezelőkkel hogy a megbízottja / kell végrehajtani, majd kijelenti egy ingatlan MyClasstípusú ( id< MyClassDelegate>), ami azt jelenti, olyan objektív c osztály, amely megfelel a a protokoll MyClassDelegate, észre fogod venni, hogy a megbízott ingatlan nyilvánították gyenge, ez nagyon fontos, hogy megakadályozzák megtartani ciklus (leggyakrabban a megbízott megtartja a MyClasspéldányt, ha bejelentett a küldött mint megtartani, mindkettő megtartja egymást, és nem ezek valaha is megjelent).
akkor veszi észre azt is, hogy a protokoll módszerek halad az MyClassesetben a küldöttnek, mint paraméter, ez a legjobb gyakorlat esetén a küldött szeretnénk felhívni néhány módszer a MyClasspéldány, és abban is segít, ha az illető résztvevő kijelenti magát MyClassDelegatetöbb MyClassesetben, például ha több UITableView'sesetekben a ViewControllerés kijelenti magát UITableViewDelegatemindet.
és azon belül a MyClassértesítse a küldött deklarált események a következők szerint:
if([_delegate respondsToSelector:@selector(myClass: requiredEventHandlerWithParameter:)])
{
[_delegate myClass:self requiredEventHandlerWithParameter:(ParamType*)param];
}
először ellenőrizze, hogy a küldött reagál a protokoll módszerrel, hogy hamarosan hívni, ha a résztvevő nem hajtják végre, és az alkalmazás összeomlik, akkor (még ha a protokoll módszerre van szükség).
Ok, ez nem igazán válasz a kérdésre, de ha keres fel, hogyan lehet a saját megbízottja talán valami sokkal egyszerűbb lehetne jobb válasz az Ön számára.
Alig végre én küldöttek, mert ritkán kell. Én csak egy küldöttet küldöttje objektumot. Tehát, ha azt szeretné, hogy küldöttet egyirányú kommunikáció / tompított adat, mint te sokkal jobb az értesítéseket.
NSNotification átadhatók tárgyak több címzettnek, és nagyon könnyen használható. Úgy működik, mint ez:
MyClass.m fájlt kell kinéznie
#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
Ahhoz, hogy a bejelentés egy másik osztály: A osztály mint megfigyelő:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(otherClassUpdatedItsData:) name:@"myClassUpdatedData" object:nil];
Végre kell hajtani a választó:
- (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
}
Ne felejtsük el eltávolítani az osztály mint megfigyelő, ha
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Íme egy egyszerű módszer segítségével küldöttek
Készítsen jegyzőkönyvet .h fájlban. Győződjön meg arról, hogy definiálni kell, mielőtt a protokollt használja @class majd a neve a UIViewController< As the protocol I am going to use is UIViewController class>.
Lépés: 1: Hozzon létre egy új osztályt jegyzőkönyv nevű „YourViewController” ez lesz az alosztálya UIViewController osztály és hozzá ez az osztály a második ViewController.
Lépés: 2: Menj a „YourViewController” fájlt, és módosítsa azt az alábbiak szerint:
#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
A módszerek meghatározott protokoll viselkedés szabályozható @optional és @required részeként a protokoll meghatározása.
Lépés: 3: végrehajtása küldötte
#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
// test, hogy a módszer került meghatározásra, mielőtt hívják
- (void) someMethodToCallDelegate {
if ([[self delegate] respondsToSelector:@selector(defineDelegateMethodName:)]) {
[self.delegate delegateMethodName:self];
}
}
A saját megbízottja, először létre kell hoznia egy protokoll és állapítsa meg a szükséges eljárások végrehajtása nélkül. És akkor végre ezt a protokollt be header osztály, ahol meg szeretne valósítani a meghatalmazott vagy megbízott módszerekkel.
A protokollt kell nyilvánítani az alábbiak szerint:
@protocol ServiceResponceDelegate <NSObject>
- (void) serviceDidFailWithRequestType:(NSString*)error;
- (void) serviceDidFinishedSucessfully:(NSString*)success;
@end
Ez a szolgáltatás osztály, ahol néhány feladatot kell elvégezni. Ez azt mutatja, hogyan határozza meg küldött és hogyan kell beállítani a küldöttet. Az implementációs osztályt után a feladat befejezése után a delegátus módszerekkel hívják.
@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
Ez a fő nézet osztályt, ahol a szolgáltatás osztály neve beállításával a küldött magának. És a protokoll végrehajtása a fejlécben osztályban.
@interface viewController: UIViewController <ServiceResponceDelegate>
{
ServiceClass* _service;
}
- (void) go;
@end
@implementation viewController
//
//some methods
//
- (void) go
{
_service = [[ServiceClass alloc] init];
[_service setDelegate:self];
[_service someTask];
}
Ennyi, és azok végrehajtásával megbízott módszerek ebben az osztályban, ellenőrzés, vissza fog térni, ha a művelet / feladat kész.
Fontos: ez a Swiftverzió, hogyan lehet létrehozni egy delegate.
Szóval, mik a küldöttek? ... a szoftverfejlesztésben, vannak általános újrahasználható megoldás architektúrák, amelyek segítenek megoldani a problémákat, általánosan előforduló adott kontextuson belül, ezek a „sablonok”, hogy úgy mondjam, a legismertebb a tervezési minták. Küldöttek a mintázata, amely lehetővé teszi egy tárgy üzenetet küldeni egy másik objektumot, amikor egy bizonyos esemény történik. Képzeljünk el egy objektum meghívja egy tárgy B művelet végrehajtásához. Miután a művelet befejeződött, az A objektum tudnia kell, hogy a B elvégezte a feladatot, és megteszi a szükséges intézkedéseket, ezt el lehet érni a segítségével küldött!
A jobb magyarázatot, megyek, hogy mutassa meg, hogyan kell létrehozni egy egyéni küldött, amely adatokat az osztályok között, a Swift egy egyszerű alkalmazás, először letölti vagy klónozó ezt starter projekt és futtatni!
Láthatjuk egy alkalmazás két osztályt, ViewController Aés ViewController B. B két nézetek, amelyek a csapot megváltoztatja a háttér színét a ViewControllersemmi túl bonyolult ugye? illetve most gondolkodjunk egy egyszerű módja annak, hogy megváltoztathatja a háttér színe osztály, amikor a véleményüket B osztályú megérintésekor.
A probléma az, hogy ez a nézet része B. osztályú és fogalma sincs arról, osztály, ezért meg kell találni a módját, hogy kommunikálni között ez a két osztály, és ez az, ahol felhatalmazás ragyog. Osztottam átültetése 6 lépésben, így tudja használni ezt a puskát, amikor szüksége van rá.
1. lépés: Keresse pragmájához védjegy 1. lépése ClassBVC fájlt és adjuk hozzá a
//MARK: step 1 Add Protocol here.
protocol ClassBVCDelegate: class {
func changeBackgroundColor(_ color: UIColor?)
}
Az első lépés, hogy hozzon létre egy protocol, ebben az esetben, akkor hozza létre a protokoll osztály B, belül a protokoll lehet létrehozni annyi kívánt funkciókat követelmények alapján a végrehajtás. Ebben az esetben már csak egy egyszerű függvény, amely elfogadja az opcionális UIColorérvként. Van egy jó gyakorlat, hogy nevezze meg protokollok hozzáadjuk a szó delegatevégén az osztály nevét, ebben az esetben ClassBVCDelegate.
2. lépés: Keresse pragmájához védjegy 2. lépése ClassVBCés adjuk hozzá a
//MARK: step 2 Create a delegate property here.
weak var delegate: ClassBVCDelegate?
Itt csak hozzon létre egy delegáltja -nak az osztály, az ingatlan el kell fogadnia a protocoltípus, és legyen kötelező. Is, akkor hozzá kell adni a gyenge kulcsszó előtt az ingatlan, hogy ne megtartani ciklusok és a potenciális memóriavesztés, ha nem tudjuk, hogy ez mit jelent ne aggódj egyelőre, csak ne feledjük, hogy a kulcsszót hozzá.
3. lépés: Keresse pragmájához védjegy a 3. lépés belsejében handleTap methoda ClassBVCés adjuk hozzá a
//MARK: step 3 Add the delegate method call here.
delegate?.changeBackgroundColor(tapGesture.view?.backgroundColor)
Egy dolog, amit tudnia kell, futtassa az alkalmazást, és érintse meg bármelyik nézetben, akkor nem jelennek meg új magatartást, és ez helyes, de a dolog, amit szeretnék rámutatni, hogy az app ez nem összeomlik, amikor a küldött hívják, és ez azért van, mert akkor hozza létre, mint egy tetszőleges értéket, és ezért ez nem fog összeomlani, még az átruházott még nem létezik. Nézzük most megy ClassAVCfájlt, és azt, akkor a megbízott.
4. lépés: Keresse pragmájához védjegy 4. lépés belsejében handleTap módszer ClassAVCés adjuk hozzá a következő az osztály típusát, mint ez.
//MARK: step 4 conform the protocol here.
class ClassAVC: UIViewController, ClassBVCDelegate {
}
Most ClassAVC elfogadta a ClassBVCDelegateprotokollt, akkor láthatjuk, hogy a fordító ad neked egy hiba, hogy azt mondja: „típus„ClassAVC nem felel meg a protokoll »ClassBVCDelegate«, és ez csak azt jelenti, hogy nem használja a módszerek a protokoll még elképzelni, hogy amikor osztály elfogadja a jegyzőkönyvet, mint a szerződés aláírása B osztályú, és ez a szerződés azt mondja: „Minden osztály elfogadása nekem KELL használni a funkciót!”
Gyors megjegyzés: Ha jön egy Objective-Cháttérkép, akkor valószínűleg arra gondolt, hogy akkor is kuss, hogy hiba, hogy ez a módszer nem kötelező, de meglepetésemre, és valószínűleg a tiéd, Swiftnyelv nem támogatja az opcionális protocols, ha meg akarja csinálni akkor létrehozhat egy bővítményt protocolvagy használja a @objc kulcsszót a protocolvégrehajtás.
Személyesen Ha létre kell hozni egy protokollt más választható módszere Inkább törni a különböző protocols, így fogom követni a koncepció, amely egyetlen felelőssége, hogy én tárgyakat, de ez függ a konkrét megvalósítására.
Itt egy jó cikket a választható módszerek.
5. lépés: Keresse pragmájához védjegy az 5. lépésben belsejében készülni váltása eljárás és adjuk hozzá a
//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
}
Itt most csak létre egy példánya ClassBVCés rendeljen küldöttje az önálló, de mi magától itt? Nos, én a ClassAVCmely ruháztak!
6. lépés: Végül, keresse pragmájához 6. lépése ClassAVCés vegyünk a funkciókat az protocolkezdje el beírni funkcionális changeBackgroundColor , és látni fogja, hogy ez az automatikus kitöltése az Ön számára. Tetszőleges végrehajtása benne, ebben a példában, akkor csak megváltoztatni a háttér színét, adjunk hozzá ezt.
//MARK: step 6 finally use the method of the contract
func changeBackgroundColor(_ color: UIColor?) {
view.backgroundColor = color
}
Most fut az alkalmazás!
Delegatesmindenhol vannak, és valószínűleg használni őket anélkül, hogy észre, ha létrehoz egy tableviewa múltban használt küldöttség számos osztálya UIKITműködik körülöttük, és még sok más frameworksis, oldják meg ezeket fő probléma.
Gratulálok, csak végre egy egyedi megbízottja, tudom, hogy valószínűleg gondolkodás, annyi baj csak erre? Nos, felhatalmazás egy nagyon fontos tervezési minta megérteni, ha azt szeretnénk, hogy egy iOSfejlesztő, és mindig szem előtt tartani, hogy azok 1-1 közötti kapcsolat objektumokat.
Láthatjuk az eredeti bemutató itt
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;
Eljárás:
-(void)delegateMEthod: (ArgType) arg{
}
A válasz tulajdonképpen nem válaszolt, de szeretnék adni egy „puskát” létrehozására küldött:
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
Kezdjük egy példát, ha veszünk egy terméket online, átesik folyamat, mint a szállítási / szállítási kezeli a különböző teams.So, ha a szállítás lesz kész, szállítás csapat értesítenie kell szállítási csapat és meg kell 1-1 kommunikációt műsorszórás ezeket az információkat lenne fölött mások / vendor érdemes átadni ezt az információt csak a szükséges embereket.
Tehát, ha úgy gondolja, tekintve a mi app, egy esemény lehet egy online rendelés és más csapatok is, mint több nézetben.
Itt látható kódot fontolóra ShippingView a Szállítási csapat & DeliveryView a szállítási csapat:
//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
//
}
}
Az én szempontból hozzon létre külön osztályt, hogy küldötte módszer, és tudod használni, ahol akar.
az én egyéni 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;
azt követően, hogy in.m fájlt létrehozni tömb tárgyak,
- (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];
}
}
}];
}
Itt minden van beállítva egyéni résztvevői class.after hogy akkor használja ezt a módszert megbízottja hol want.for példa ...
az én másik viewcontroller import után
akció létrehozása a hívó küldötte módszer, mint ez
- (IBAction)dropDownBtn1Action:(id)sender {
DropDownViewController *vehicleModelDropView = [[DropDownViewController alloc]init];
vehicleModelDropView.dropDownType = DDCITY;
vehicleModelDropView.delegate = self;
[self presentViewController:vehicleModelDropView animated:YES completion:nil];
}
után a hívás résztvevői módszer, mint ez
- (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;
}
}
//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. Végrehajtása módszer az osztályban .m - (void) didRemoveCellWithTag: (NSInteger) kulcsszó {NSLog @ ( "Tag% d", tag);
}
Delegálása: - Készítsd
@protocol addToCartDelegate <NSObject>
-(void)addToCartAction:(ItemsModel *)itemsModel isAdded:(BOOL)added;
@end
Küldj és kérjük hozzá küldött megtekinteni az Ön által küldött adatok
[self.delegate addToCartAction:itemsModel isAdded:YES];