Jak wykonać wywołania zwrotne w Objective-C

Jak wykonywać funkcje call back w Objective-C?

Chciałbym zobaczyć kilka gotowych przykładów i powinienem to zrozumieć.

Author: ROMANIA_engineer, 2009-06-19

5 answers

Zwykle wywołania zwrotne w objective C są wykonywane przez delegatów. 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

Implementacja (.M) Plik

@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 nie implementuje tych metod. Ten typ kategorii nazywa się nieformalnym protokołem, mówisz tylko, że wiele obiektów może zaimplementować te metody. Są sposobem na przekazanie podpisu typu selektora.

Następnie masz jakiś obiekt be the delegate of" MyClass " i MyClass wywołuje metody delegata w delegacie odpowiednio. Jeśli wywołania zwrotne delegata są opcjonalne, zazwyczaj będziesz je chronić w miejscu wysyłki za pomocą czegoś w rodzaju " if ([delegate respondsToSelector:@selector (myClassWillDoSomething:)) {". W moim przykładzie delegat jest wymagany do wdrożenia obu metod.

Zamiast protokół nieformalny, można również użyć protokołu formalnego zdefiniowanego za pomocą @protocol. Jeśli to zrobisz, zmienisz Typ ustawiacza delegatów i zmienną instancji na " id <MyClassDelegate> "zamiast tylko"id".

Zauważysz również, że delegat nie jest zachowany. Zazwyczaj dzieje się tak, ponieważ obiekt, który "posiada" instancje "MyClass", jest zazwyczaj również delegatem. Jeśli MyClass zachowa swojego delegata, wtedy będzie cykl zachowywania. To dobry pomysł w metodzie dealloc klasy, która to ma instancję MyClass i jest jej delegatem, aby wyczyścić odniesienie do delegata, ponieważ jest słabym wskaźnikiem wstecz. W przeciwnym razie, jeśli coś utrzymuje instancję MyClass przy życiu, będziesz miał zwisający wskaźnik.

 92
Author: Jon Hess,
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-03-20 19:17:14

Dla kompletności, ponieważ StackOverflow RSS właśnie losowo wskrzesił dla mnie pytanie, drugą (nowszą) opcją jest użycie bloków:

@interface MyClass: NSObject
{
    void (^_completionHandler)(int someParameter);
}

- (void) doSomethingWithCompletionHandler:(void(^)(int))handler;
@end


@implementation MyClass

- (void) doSomethingWithCompletionHandler:(void(^)(int))handler
{
    // NOTE: copying is very important if you'll call the callback asynchronously,
    // even with garbage collection!
    _completionHandler = [handler copy];

    // Do stuff, possibly asynchronously...
    int result = 5 + 3;

    // Call completion handler.
    _completionHandler(result);

    // Clean up.
    [_completionHandler release];
    _completionHandler = nil;
}

@end

...

MyClass *foo = [[MyClass alloc] init];
int x = 2;
[foo doSomethingWithCompletionHandler:^(int result){
    // Prints 10
    NSLog(@"%i", x + result);
}];
 133
Author: Jens Ayton,
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
2010-10-12 14:33:55

Oto przykład, który utrzymuje koncepcje delegatów, i po prostu wykonuje surowe wywołanie.

@interface Foo : NSObject {
}
- (void)doSomethingAndNotifyObject:(id)object withSelector:(SEL)selector;
@end

@interface Bar : NSObject {
}
@end

@implementation Foo
- (void)doSomethingAndNotifyObject:(id)object withSelector:(SEL)selector {
    /* do lots of stuff */
    [object performSelector:selector withObject:self];
}
@end

@implementation Bar
- (void)aMethod {
    Foo *foo = [[[Foo alloc] init] autorelease];
    [foo doSomethingAndNotifyObject:self withSelector:@selector(fooIsDone:)];
}

- (void)fooIsDone:(id)sender {
    NSLog(@"Foo Is Done!");
}
@end

Zazwyczaj metoda - [Foo doSomethingAndNotifyObject: withSelector:] byłaby asynchroniczna, co uczyniłoby wywołanie zwrotne bardziej użytecznym niż tutaj.

 48
Author: Jon Hess,
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
2010-10-12 07:49:32

Aby to pytanie było aktualne, wprowadzenie w systemie iOS 5.0 Arc oznacza, że można to osiągnąć za pomocą bloków jeszcze bardziej zwięźle:

@interface Robot: NSObject
+ (void)sayHi:(void(^)(NSString *))callback;
@end

@implementation Robot
+ (void)sayHi:(void(^)(NSString *))callback {
    // Return a message to the callback
    callback(@"Hello to you too!");
}
@end

[Robot sayHi:^(NSString *reply){
  NSLog(@"%@", reply);
}];

Zawsze jest F * * * ng składnia blokowa Jeśli kiedykolwiek zapomnisz składnię blokową Objective-C.

 5
Author: Ryan Brodie,
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
2016-03-31 11:33:23

CallBack: Istnieją 4 rodzaje callback w celu C

  1. Typ selektora: możesz zobaczyć NSTimer,UIPangesture są przykładami wywołania zwrotnego selektora. Używany do bardzo ograniczonego wykonywania kodu.

  2. Typ delegata : popularny i najczęściej używany w frameworku Apple. UITableViewDelegate, NSNURLConnectionDelegate. Są one zwykle używane do pokazywania pobierania wielu obrazów z serwera asynchronicznie itp.

  3. NSNotifications : NotificationCenter jest jedną z funkcji Objective C, która służy do powiadamiania wielu odbiorców w momencie wystąpienia zdarzenia.
  4. bloki : bloki są częściej używane w programowaniu Objective C. Jest to świetna funkcja i służy do wykonywania fragmentów kodu. Można również odnieść tutorial zrozumieć : bloki tutorial

Proszę pozwolić mi, jeśli jakaś inna odpowiedź na to. Będę wdzięczny.

 3
Author: Anil Gupta,
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
2016-10-13 07:47:31