Sovrascrivere i metodi utilizzando le categorie in Objective-C


87

Posso utilizzare una categoria di classe per sostituire un metodo già implementato utilizzando una categoria? Come questo:

1) Metodo originale

-(BOOL) method {
  return true;
}

2) Metodo ignorato

-(BOOL) method {
  NSLog(@"error?"); 
  return true; 
}

Funzionerà o è illegale?

Risposte:


147

Dalla documentazione Apple :

Sebbene il linguaggio Objective-C attualmente consenta di utilizzare una categoria per sovrascrivere i metodi ereditati dalla classe, o anche i metodi dichiarati nell'interfaccia della classe, è fortemente sconsigliato farlo . Una categoria non è un sostituto di una sottoclasse. Esistono diverse carenze significative nell'utilizzo di una categoria per sostituire i metodi:

  • Quando una categoria sovrascrive un metodo ereditato, il metodo nella categoria può, come al solito, richiamare l'implementazione ereditata tramite un messaggio a super. Tuttavia, se una categoria sovrascrive un metodo che esiste nella classe della categoria, non è possibile richiamare l'implementazione originale .

  • Una categoria non può sostituire in modo affidabile i metodi dichiarati in un'altra categoria della stessa classe.

    Questo problema è di particolare importanza perché molte delle classi Cocoa vengono implementate utilizzando le categorie. Un metodo definito dal framework che si tenta di sovrascrivere potrebbe essere stato implementato in una categoria, quindi quale implementazione ha la precedenza non è definita.

  • La stessa presenza di alcuni metodi di categoria può causare cambiamenti di comportamento in tutti i framework. Ad esempio, se si sovrascrive il windowWillClose:metodo delegato in una categoria su NSObject, tutti i delegati della finestra nel programma rispondono utilizzando il metodo categoria; il comportamento di tutte le istanze di NSWindow potrebbe cambiare. Le categorie aggiunte a una classe framework possono causare misteriosi cambiamenti nel comportamento e portare a crash.


Grazie ma lo so già. Mi chiedo solo se il mio caso sia legale o meno. Il mio caso è leggermente diverso dai documenti. :)
retix

Perché è diverso? Il documento dice che è legale SE il metodo originale non è in una categoria, ma è fortemente sconsigliato. Allora puoi farlo ...
Benoît

1
Grazie per il consiglio. Sono povero in questa lingua. Ho nuove informazioni da te.
retix

1
È corretto sovrascrivere nel metodo Category dichiarato e implementato in Category of super class?
BergP

2
Il collegamento è interrotto, è questa la nuova versione? developer.apple.com/library/ios/documentation/Cocoa/Conceptual/…
RndmTsk


9

Il vecchio collegamento alla documentazione è morto; il miglior sostituto che ho trovato era qui: Documenti Apple :

Evita conflitti di nomi di metodi di categoria

Poiché i metodi dichiarati in una categoria vengono aggiunti a una classe esistente, è necessario prestare molta attenzione ai nomi dei metodi.

Se il nome di un metodo dichiarato in una categoria è lo stesso di un metodo nella classe originale, o di un metodo in un'altra categoria sulla stessa classe (o anche una superclasse), il comportamento non è definito per quanto riguarda l'implementazione del metodo utilizzata in runtime. È meno probabile che questo sia un problema se stai usando categorie con le tue classi, ma può causare problemi quando usi le categorie per aggiungere metodi alle classi standard Cocoa o Cocoa Touch.

È Apple che usa un tocco più leggero, ma il punto principale è lo stesso: inviti il ​​disastro, perché il comportamento imprevedibile è silenzioso.


2

È importante notare che una categoria può essere utilizzata anche per sovrascrivere i metodi esistenti nella classe base (ad esempio, il metodo drive della classe Car), ma non dovresti mai farlo. Il problema è che le categorie sono una struttura organizzativa piatta. Se si sovrascrive un metodo esistente in Car + Maintenance.m e quindi si decide di modificarne nuovamente il comportamento con un'altra categoria, Objective-C non può sapere quale implementazione utilizzare. La sottoclasse è quasi sempre un'opzione migliore in una situazione del genere.

Da questo tutorial, http://rypress.com/tutorials/objective-c/categories

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.