Jak wykonywać funkcje oddzwaniania w Objective-C?
Chciałbym tylko zobaczyć kilka ukończonych przykładów i powinienem to zrozumieć.
źródło
Jak wykonywać funkcje oddzwaniania w Objective-C?
Chciałbym tylko zobaczyć kilka ukończonych przykładów i powinienem to zrozumieć.
Zwykle wywołania zwrotne w celu C są wykonywane z delegatami. Oto przykład niestandardowej implementacji delegata;
Plik nagłówkowy:
@interface MyClass : NSObject {
id delegate;
}
- (void)setDelegate:(id)delegate;
- (void)doSomething;
@end
@interface NSObject(MyDelegateMethods)
- (void)myClassWillDoSomething:(MyClass *)myClass;
- (void)myClassDidDoSomething:(MyClass *)myClass;
@end
Plik implementacji (.m)
@implementation MyClass
- (void)setDelegate:(id)aDelegate {
delegate = aDelegate; /// Not retained
}
- (void)doSomething {
[delegate myClassWillDoSomething:self];
/* DO SOMETHING */
[delegate myClassDidDoSomething:self];
}
@end
To ilustruje ogólne podejście. Tworzysz kategorię na NSObject, która deklaruje nazwy twoich metod wywołania zwrotnego. NSObject w rzeczywistości nie implementuje tych metod. Ten typ kategorii nazywa się protokołem nieformalnym, po prostu mówisz, że wiele obiektów może implementować te metody. Są sposobem na przekazanie dalej deklaracji typu selektora.
Następnie masz jakiś obiekt będący delegatem „MyClass” i MyClass wywołuje metody delegata na delegacie, jeśli jest to wymagane. Jeśli wywołania zwrotne Twojego delegata są opcjonalne, zazwyczaj będziesz ich strzegł w miejscu wysyłki za pomocą czegoś takiego jak „if ([delegate respondsToSelector: @selector (myClassWillDoSomething :)) {". W moim przykładzie delegat musi zaimplementować obie metody.
Zamiast nieformalnego protokołu można również użyć formalnego protokołu zdefiniowanego za pomocą @protocol. Jeśli to zrobisz, zmienisz typ metody ustawiającej delegata i zmiennej instancji na „ id <MyClassDelegate>
” zamiast tylko „ id
”.
Zauważysz również, że delegat nie jest zatrzymany. Dzieje się tak zazwyczaj, ponieważ obiekt, który jest „właścicielem” wystąpień „MyClass”, jest zazwyczaj również delegatem. Gdyby MyClass zachował swojego delegata, wystąpiłby cykl przechowywania. W metodzie dealloc klasy, która ma instancję MyClass i jest jej delegatem, dobrym pomysłem jest wyczyszczenie odwołania do delegata, ponieważ jest to słaby wskaźnik wsteczny. W przeciwnym razie, jeśli coś utrzymuje instancję MyClass przy życiu, będziesz mieć wiszący wskaźnik.
Dla kompletności, ponieważ StackOverflow RSS po prostu losowo wskrzesił pytanie dla mnie, drugą (nowszą) opcją jest użycie bloków:
źródło
Oto przykład, który usuwa koncepcje delegatów i po prostu wykonuje nieprzetworzone wywołanie zwrotne.
Zazwyczaj metoda - [Foo doSomethingAndNotifyObject: withSelector:] byłaby asynchroniczna, co uczyniłoby wywołanie zwrotne bardziej użytecznym niż tutaj.
źródło
Aby to pytanie było aktualne, wprowadzenie ARC w iOS 5.0 oznacza, że można to osiągnąć za pomocą Blocks jeszcze bardziej zwięźle:
Zawsze jest F **** ng Block Składnia, jeśli kiedykolwiek zapomnisz składni Block Objective-C.
źródło
+ (void)sayHi:(void(^)(NSString *reply))callback;
nie+ (void)sayHi:(void(^)(NSString *))callback;
- (void)someMethodThatTakesABlock:(returnType (^nullability)(parameterTypes))blockName;
(UwagaparameterTypes
nieparameters
)CallBack: istnieją 4 typy wywołań zwrotnych w celu C
Typ selektora : możesz zobaczyć NSTimer, UIPangesture to przykłady wywołania zwrotnego selektora. Używany do bardzo ograniczonego wykonywania kodu.
Typ delegata : typowy i najczęściej używany w środowisku Apple. UITableViewDelegate, NSNURLConnectionDelegate. Zwykle są używane do wyświetlania asynchronicznego pobierania wielu obrazów z serwera itp.
Proszę, pozwól mi odpowiedzieć na to pytanie. Docenię to.
źródło