2009-11-01 4 views
19

Cerca una risposta a questa domanda, ma non ne ho ancora trovato uno adatto. Spero che voi ragazzi (e ragazze) potete aiutarmi! (Questo è per un'app per iPhone)Accesso al metodo da altre classi Obiettivo-C

OK, ho un'applicazione Mutliview. Ogni vista ha la sua classe e tutto è felice. Tuttavia, le diverse classi a volte chiamano lo stesso metodo. Fino ad ora, ho semplicemente scritto quel Metodo due volte, in entrambi i file di classe.

Questo è quello che voglio fare però:

Voglio fare una nuova classe, nel file di E, che ha tutti i metodi "comuni". Quindi, ogni volta che un'altra classe ha bisogno di chiamare il metodo, lo chiamo semplicemente dall'altro file. In questo modo, quando voglio cambiare il Metodo, ho solo bisogno di cambiarlo in un posto, e non tutti i posti ...

Non sono sicuro di come lo farei, ed è per questo che I ' Sto chiedendo aiuto. Sono un po 'arrugginito e nuovo per Objective-C, quindi molti esempi mi aiuteranno molto. Permettimi di dartene uno.

File: ViewController1.m

@implementation ViewController1 

//Do Some awesome stuff.... 

CALL "CommonMethod" HERE 

@end 

File: ViewController2.m

@implementation ViewController2 

//Do Some awesome stuff.... 

CALL "CommonMethod" HERE 

@end 

File: CommonClass

@implementation commonClass 

- (void)CommonMethod:(id)sender 
{ 

//So some awesome generic stuff... 



    } 
@end 

mi sento come se ho bisogno di #import l'altro file, crea un oggetto dalla classe e chiama il metodo dall'oggetto ... Come faccio?

Grazie ancora!

risposta

26

Opzione 1:

@implementation commonClass 
+ (void)CommonMethod:(id)sender /* note the + sign */ 
{ 
//So some awesome generic stuff... 
    } 
@end 

@implementation ViewController2 

- (void)do_something... { 
    [commonClass CommonMethod]; 
} 


@end 

Opzione 2:

@implementation commonClass 
- (void)CommonMethod:(id)sender 
{ 
//So some awesome generic stuff... 
    } 
@end 

@implementation ViewController2 

- (void)do_something... { 
    commonClass *c=[[commonClass alloc] init]; 
    [c CommonMethod]; 
    [c release]; 
} 

@end 

Opzione 3: utilizzare l'ereditarietà (vedi descrizione del signor Totland in questa discussione)

@implementation commonClass 
- (void)CommonMethod:(id)sender 
{ 
//So some awesome generic stuff... 
    } 
@end 

/* in your .h file */ 
@interface ViewController2: commonClass 

@end 

naturalmente è sempre necessario a #import commonClass.h nella vista controller.

+0

Ciao, qual è la super classe di commonClass qui? Voglio dire che ho un metodo che ho bisogno di chiamare da molte classi diverse, quindi quale sarà la migliore pratica per questo? –

+0

È '[proprietà release]' permesso in modalità ARC? Il compilatore mi sta dicendo che non è permesso. – tymac

+0

@tymac Questo post è del 2009, prima di ARC. –

3

Mi sembra che il codice comune non abbia bisogno di essere in una classe. C'è una ragione per cui non puoi semplicemente usare una funzione in stile C per quello che vuoi fare?

È possibile inserire il codice comune in una classe e quindi creare le sottoclassi delle altre due classi di quella classe; questo metodo evita anche la duplicazione del codice.

Un'altra opzione potrebbe essere quella di scrivere un metodo di classe anziché i metodi di istanza per questo codice comune. Penso che molte persone ritengano che i singleton siano meglio evitati come scelta di design.

Sarebbe più facile dare una buona risposta se sapessimo di più su ciò che stavi davvero cercando di realizzare.

+0

Sembra essere un problema di non sfruttare l'ereditarietà. –

+0

Grazie. Ho avuto un metodo (metodo1) in Class1. L'ho dichiarato in Class1.h e implementato in Class1.m. Ho Class2 e ha un selettore: @selector (metodo1). In questo caso, come posso farlo? –

+1

@Williham, è così che sembra. @ srikanth, forse hai bisogno di fare una domanda invece di pubblicare semplicemente un commento qui? –

3

Che cosa si vuole fare è quello di rendere i due controllori condividono una superclasse comune:

UIViewController : MyAwesomeViewController : ViewController1 
              : ViewController2 

commonMethod: sarebbe poi risiedere in MyAwesomeViewController. Inoltre, non iniziare i nomi dei metodi con lettere maiuscole. :)

Elaborare:

[email protected] MyAwesomeController : UIViewController { 

[email protected] ViewController1 : UIViewController { // and ditto for ViewController2 
[email protected] ViewController1 : MyAwesomeController { 
+0

+1 l'ereditarietà è la strada da percorrere. –

1

Tenete a mente che Objective-C è solo un superset di C, e che, mentre le direttive # include vengono per lo più utilizzati per i file di intestazione, non c'è nulla ti impedisce utilizzando un # includere per incorporare i contenuti di un'implementazione all'interno di un'altra implementazione. Se il codice è veramente identico, puoi semplicemente incollarlo nel suo file e # includerlo nel file .m.

Detto questo, forse sarebbe meglio usare questa tecnica insieme alle categorie, soprattutto se la stessa implementazione ha comportamenti simili.

1

passa un riferimento al tuo commonClass quando si alloc e init vostre opinioni ...

CommonClass *cc = [[CommonClass alloc] init]; 

ViewController1 *vc1 = [[ViewController1 alloc] ... initWith:cc]; 
ViewController2 *vc2 = [[ViewController2 alloc] ... initWith:cc]; 

ma fare un classico c includono potrebbe bastare.

6

Qui ci sono alcune risposte che ti dicono di creare una classe "genitore" comune. Comunque penso che tu possa fare molto meglio. Creare invece un category per UIViewController. Non si conoscono tutti i componenti interni di ciò che accade con UIViewController, quindi non penso che valga la pena creare la propria gerarchia di View Controller al di fuori di. In effetti potrebbe essere pericoloso. Ho incontrato una serie di problemi quando ho cercato di creare un UITableViewController "di base" e quindi creare classi che ereditassero da quello. Ho evitato questi problemi utilizzando invece le categorie.

La priorità numero 1 non dovrebbe ereditare le cose senza una buona ragione, dovrebbe essere trovare un'app nell'app store che le persone vorranno scaricare.

+0

+1 per il para finale ... –

0

Come un neofita di iPhone con uno sfondo Java e una piccola C, ho avuto un problema simile che volevo fare riferimento a un metodo in RootController e in un ViewController. Mi sembrava che il posto giusto per il metodo era la classe AppDelegate, un'istanza di cui si ottiene in altre classi da:

MyAppDelegate *delegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate]; 

quindi se il metodo è "doSomething" si accede facendo:

[delegate doSomething]; 

Ma forse questo è troppo ovvio o non è necessario.

0

Un altro metodo che è possibile utilizzare

@interface ServerManager : NSObject 

+(ServerManager *)getInstance; 

@implementation ServerManager 

+(ServerManager *)getInstance 
{ 
static ServerManager *objServerManager = nil; 

if(objServerManager==NULL){ 
objServerManager=[[self alloc] init]; 
} 
// Return the servermanager object. 
return objServerManager; 
} 

chiamata Se si desidera utilizzare

ServerManager *SMObject = [ServerManager getInstance]; 

Non dimenticare di importare file di servermanager.h.