2017-01-04 1 views
1

Ich verwende eine Kategorie auf UIViewController, um die viewWillAppear: -Methode über mehrere ViewControllers zu übertragen.UIViewController-Methode swizzling funktioniert nicht

@implementation UIViewController (Tracking) 

+(void)load 
{ 
    static dispatch_once_t onceToken; 

    dispatch_once(&onceToken, ^{ 
     Class class = [self class]; 

     SEL originalSelector = @selector(viewWillAppear:); 
     SEL swizzledSelector = @selector(xx_viewWillAppear:); 

     Method originalMethod = class_getInstanceMethod(class, originalSelector); 
     Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); 

     BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); 

     if (didAddMethod) 
     { 
      class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); 
     }else{ 
      method_exchangeImplementations(originalMethod, swizzledMethod); 
     } 

    }); 
} 

-(void)xx_viewWillAppear:(BOOL)animated 
{ 
    [self xx_viewWillAppear:animated]; 

    NSLog(@"VC loaded"); 
} 

@end 

Wenn ich den anfänglichen VC von Storyboard laden, wird die Swizzled-Methode nie aufgerufen. Es wird nur aufgerufen, wenn die viewWillAppear-Methode in VC auskommentiert ist. Wenn ich jedoch die Kategorie entferne und den Code in den einzelnen VC verschiebe, werden beide Methoden aufgerufen.

Ist es in Ordnung, die ViewWillAppear in VC zu implementieren, wenn es umgewechselt werden soll? Wenn nicht, wie gehe ich damit um, wenn ich Code in der VC-Ansicht schreiben mussWillAppear?

+0

Versuchen nur 'method_exchangeImplementations', ohne Zusatz, wie das Verfahren bereits Teil Ihrer Erweiterung vorhanden ist. – Cristik

+1

Auch Sie swizelling die Methode aus der Basisklasse, überschreiben es in Ihrer benutzerdefinierten Klasse bedeutet, dass Sie "Super" aufrufen müssen, um die Swizzled-Methode ausgeführt – Cristik

+0

@Cristik Ich verwende eine Kategorie und ich bin nicht Unterklasse der VC . – KrishnaKumar

Antwort

2

Sie benötigen super in Ihrem viewWillAppear: von ViewController zu nennen, da sonst das Verfahren von der Basisklasse (UIViewController) wird nicht ausgeführt, und das ist die, die Sie umgestellt.

Die folgende Version von viewWillAppear: sollten Sie die erwarteten Ergebnisse:

-(void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    NSLog(@"Inside Controller1"); 
} 
Verwandte Themen