Hoe u terugbelt in Objective-C

Hoe terugbelfuncties uitvoeren in Objective-C?

Ik zou graag enkele voltooide voorbeelden willen zien en ik zou het moeten begrijpen.


Antwoord 1, autoriteit 100%

Voor de volledigheid, aangezien StackOverflow RSS de vraag gewoon willekeurig voor mij heeft doen herleven, is de andere (nieuwere) optie om blokken te gebruiken:

@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);
}];

Antwoord 2, autoriteit 67%

Normaal gesproken worden callbacks in doelstelling C gedaan met afgevaardigden. Hier is een voorbeeld van een aangepaste implementatie van gedelegeerden;


Koptekstbestand:

@interface MyClass : NSObject {
    id delegate;
}
- (void)setDelegate:(id)delegate;
- (void)doSomething;
@end
@interface NSObject(MyDelegateMethods)
- (void)myClassWillDoSomething:(MyClass *)myClass;
- (void)myClassDidDoSomething:(MyClass *)myClass;
@end

Implementatiebestand (.m)

@implementation MyClass
- (void)setDelegate:(id)aDelegate {
    delegate = aDelegate; /// Not retained
}
- (void)doSomething {
    [delegate myClassWillDoSomething:self];
    /* DO SOMETHING */
    [delegate myClassDidDoSomething:self];
}
@end

Dat illustreert de algemene benadering. U maakt een categorie op NSObject die de namen van uw callback-methoden declareert. NSObject implementeert deze methoden niet echt. Dit type categorie wordt een informeel protocol genoemd, je zegt alleen dat veel objecten deze methoden kunnen implementeren. Ze zijn een manier om de typehandtekening van de selector door te geven.

Vervolgens heb je een object dat de gemachtigde van “MyClass” is en MyClass roept de gemachtigde methoden op de gemachtigde aan zoals van toepassing. Als het terugbellen van uw gedelegeerde optioneel is, bewaakt u ze meestal op de verzendsite met iets als “if ([delegate respondsToSelector:@selector(myClassWillDoSomething:)) {“. In mijn voorbeeld moet de gemachtigde beide methoden implementeren.

In plaats van een informeel protocol kunt u ook een formeel protocol gebruiken dat is gedefinieerd met @protocol. Als u dat doet, wijzigt u het type delegate setter en de instantievariabele in “id <MyClassDelegate>” in plaats van alleen “id“.

Ook zult u merken dat de gemachtigde niet wordt behouden. Dit wordt meestal gedaan omdat het object dat instanties van “MyClass” “bezit”, meestal ook de gemachtigde is. Als MyClass zijn afgevaardigde zou behouden, zou er een bewaarcyclus zijn. Het is een goed idee om in de dealloc-methode van een klasse die een MyClass-instantie heeft en zijn gemachtigde is, de verwijzing van die gemachtigde te wissen, omdat het een zwakke terugwijzer is. Anders, als iets de MyClass-instantie in leven houdt, heb je een bungelende aanwijzer.


Antwoord 3, autoriteit 38%

Hier is een voorbeeld dat de concepten van afgevaardigden buiten de deur houdt, en gewoon een onbewerkte oproep doet.

@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

Normaal gesproken zou de methode -[Foo doSomethingAndNotifyObject:withSelector:] asynchroon zijn, wat het terugbellen nuttiger zou maken dan hier het geval is.


Antwoord 4, autoriteit 13%

Om deze vraag actueel te houden, betekent de introductie van ARCin iOS 5.0 dit kan worden bereikt met behulp van zelfs Blocksbeknopter:

@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);
}];

Er is altijd F****ng Block Syntaxals je ooit de Block-syntaxis van Objective-C vergeet.


Antwoord 5, autoriteit 4%

Terugbellen: er zijn 4 soorten terugbellen in Doelstelling C

  1. Type selector: u kunt zien dat NSTimer, UIPangesture voorbeelden zijn van Selector callback. Gebruikt voor zeer beperkte uitvoering van code.

  2. Type gedelegeerde: algemeen en meest gebruikt in Apple-framework. UITableViewDelegate, NSNURLConnectionDelegate. Ze worden meestal gebruikt om het downloaden van veel afbeeldingen van de server asynchroon enz. weer te geven.

  3. NSNotifications: NotificationCenter is een van de functies van Objective C die vroeger veel ontvangers op de hoogte bracht op het moment dat zich een gebeurtenis voordeed.
  4. Blokken: Blokken worden vaker gebruikt in Objective C-programmering. Het is een geweldige functie en wordt gebruikt voor het uitvoeren van een stuk code. Je kunt ook de tutorial raadplegen om het te begrijpen: Blocks tutorial

Laat me alsjeblieft een ander antwoord geven. Ik zal het op prijs stellen.

Other episodes