Sostituire un metodo tramite Categoria ObjC e chiamare l’implementazione predefinita?

Quando si utilizzano le categorie, è ansible sovrascrivere i metodi di implementazione con il proprio in questo modo:

// Base Class @interface ClassA : NSObject - (NSString *) myMethod; @end @implementation ClassA - (NSString*) myMethod { return @"A"; } @end //Category @interface ClassA (CategoryB) - (NSString *) myMethod; @end @implementation ClassA (CategoryB) - (NSString*) myMethod { return @"B"; } @end 

Chiamando il metodo “myMethod” dopo aver incluso le reti di categoria, il risultato “B”.

Qual è il modo più semplice per l’implementazione di Categoria di myMethod per chiamare la class originale MyMethod? Per quanto riesca a capire, dovresti usare le chiamate di basso livello per ottenere il metodo originale di aghook per la Classe A e chiamarlo, ma sembrava che ci sarebbe stato un modo sintatticamente più semplice per farlo.

Se vuoi un modo di fare hacker che coinvolga il runtime oggettivo-c puoi sempre usare il metodo swizzling (inserisci qui le dichiarazioni di non responsabilità standard). Ti permetterà di memorizzare i diversi metodi come selettori arbitrarili chiamati, quindi scambiarli in runtime quando ne hai bisogno.

Dalla lista di domande frequenti su comp.lang.objective-C : ” Cosa succede se più categorie implementano lo stesso metodo?” Quindi il tessuto dell’Universo come lo conosciamo cessa di esistere. In realtà, non è del tutto vero, ma sicuramente alcuni problemi saranno causati. Quando una categoria implementa un metodo che è già apparso in una class (sia attraverso un’altra categoria, o la class ‘primary @implementation), la definizione di quella categoria sovrascrive la definizione che era precedentemente presente.La definizione originale non può più essere raggiunta dall’Obiettivo -C codice. Si noti che se due categorie sovrascrivono lo stesso metodo, a seconda di quale sia stato caricato l’ultimo “wins”, potrebbe non essere ansible prevedere prima che il codice venga avviato. ”

Da developer.apple.com : “Quando una categoria sovrascrive un metodo ereditato, il metodo nella categoria può, come al solito, invocare l’implementazione ereditata tramite un messaggio a super. Tuttavia, se una categoria sostituisce un metodo già esistente nella categoria class, non c’è modo di invocare l’implementazione originale ”

Controlla il mio articolo su una soluzione trovata nella Libreria per sviluppatori Mac: http://codeshaker.blogspot.com/2012/01/calling-original-overridden-method-from.html

Fondamentalmente, è lo stesso del metodo precedente Swizzling con un breve esempio:

 #import 

 @implementation Test (Logging)

 - (NSUInteger) logLength {
     NSUInteger length = [self logLength];
     NSLog (@ "Logging:% d", lunghezza);
     ritorno lunghezza;
 }

 + (vuoto) carico {
     method_exchangeImplementations (class_getInstanceMethod (self, @selector (length)), class_getInstanceMethod (self, @selector (logLength)));
 }

 @fine

Con i metodi “helper” di swizzling inclusi in ConciseKit , in realtà si chiama l’implementazione predefinita … abbastanza stranamente … chiamando l’implementazione SWIZZLED ..

Lo si imposta in + (void) load , chiamando + (BOOL)swizzleMethod:(SEL)originalSelector with:(SEL)anotherSelector in:(Class)klass; , cioè

 [$ swizzleMethod:@selector(oldTired:) with:@selector(swizzledHotness:) in:self.class]; 

e poi nel metodo swizzled .. supponiamo che ritorni -(id) .. tu puoi fare il tuo male, o qualunque ragione tu stia girando in primo luogo … e poi, invece di restituire un object, o self , o whatnot. .

 return [self swizzledHotness:yourSwizzledMethodsArgument]; 

Come spiegato qui …

In questo metodo, sembra che stiamo chiamando di nuovo lo stesso metodo, causando una ricorsione infinita. Ma nel momento in cui questa linea viene raggiunta, i due metodi sono stati scambiati. Quindi, quando chiamiamo swizzled_synchronize, stiamo effettivamente chiamando il metodo originale.

Sembra strano, ma … funziona. Ciò ti consente di aggiungere infiniti abbellimenti ai metodi esistenti, e comunque di “chiamare super” (in realtà te stesso) e di cogliere i benefici del lavoro manuale del metodo originale … anche senza accesso alla fonte originale.