2014-09-28 14 views
18

Avere un obiettivo Classe C di base:Accesso variabili di istanza Objective-c della classe base da una classe Swift

@interface ObjcClass : NSObject { 
    NSString *aVariable_; 
} 

E una rapida sotto-classe:

class SwiftClass : ObjcClass { 
    func init() { 
     // aVariable_ can't be accessed here. An Objective-c derived 
     // class has direct access to it's super's instance variables! 
    } 
} 

Come posso accedere ObjcClassaVariable_ da all'interno di SwiftClass?

risposta

5

Non riuscivo a trovare un modo "corretto" per farlo, ma avevo bisogno che funzionasse male. La mia soluzione era quella di creare un semplice metodo getter nel mio Objective C superclasse, in questo modo:

file di intestazione

@interface ObjcClass : NSObject { 
    NSString *myVariable; 
} 
- (NSString *)getMyVariable; 


nel file di implementazione

- (NSString *)getMyVariable { 
    return myVariable; 
} 

I' Mi piacerebbe sentire un modo migliore di farlo, ma almeno questo funziona.

+1

Vorrei suggerire la forma nominale '- (NSString *) myVariable'. Per convenzione, il prefisso "get" viene in genere utilizzato quando i risultati vengono restituiti per riferimento (ad esempio, 'NSArray''s' - (void) getObjects: (id []) intervallo del buffer: (NSRange) range'). Meglio ancora, usa una proprietà come suggeriscono altre risposte. –

17

Ottima richiesta. Abbiamo cercato di ottenere risultati difficili. L'unica soluzione di lavoro ho trovato

valore GET utilizzando self.valueForKey("aVariable_")

valore impostato utilizzando self.setValue("New Value", forKey: "aVariable_")

Speranza che aiuta. Possibile soluzione senza alterare la super classe.

+0

Questo è quello che ho fatto. Mi piace la risposta di @ JasonTyler però. – Shai

+0

Grazie a @Narendra Per me preferisco in questo modo se lascia var aVar = self.valueForKey ("aVariable_") come se il tuo codice fosse in Swift e usi una libreria Objective C che non puoi modificare. Funziona alla grande. – Dam

+0

Questo è il modo più semplice, anche il controllo del tipo di lago. –

3

Ho cercato molto per questo. Alla fine ho cambiato il mio codice da:

@interface PrjRec : NSObject { 
    @public 
    NSString* name; 
} 
@end 

A:

@interface PrjRec : NSObject { 
} 

@property NSString* name; 

@end 

simile alla soluzione @JasonTyler. Allora posso accedere al mio proprietà dell'oggetto dal codice Swift con una semplice notazione <object instance>.name,

Ma avevo bisogno di cambiare tutti i riferimenti Objective-C esistenti dalla

<object instance>->name 

A:

<object instance>.name 

oppure

_name 

se unità interna.

Spero anche in una soluzione migliore.

0

Se si desidera avere una proprietà, è possibile creare la proprietà in base alle proprie esigenze.

@interface ObjcClass : NSObject { 
    NSString *aVariable_; 
} 

@property (nonatomic) NSString *aVariable_; 

...

@implementation ObjcClass 

@synthesize aVariable_ = aVariable_; 

questo modo la variabile a cui accedere come inst->aVariable_ o come inst.aVariable_. Nella classe Objective C è possibile accedere alla variabile come aVariable_ o self.aVariable_.

0

Non so seriamente perché qualcuno faccia più le variabili di istanza (per esempio, sono private di default) rispetto alle proprietà. Vedi la risposta di Giorgio Calzolato su questo (a parte la sua ultima battuta sulla ricerca di una soluzione migliore - questa è la soluzione migliore :)).

Nel mio caso avevo già una proprietà ed ero extra perplesso sul motivo per cui non funzionava. Ma mi sono reso conto che la proprietà aveva un tempo personalizzato e doveva essere aggiunta al mio file SDK-Bridging-Header.h.

Quindi, se la vostra proprietà è impostata su un tipo personalizzato come questo:

@property (nonatomic, weak) IBOutlet SDKMyCustomObject *customObject; 

... poi ricordare per aggiungerlo alla testata di ponte.

1

questo ha funzionato come una soluzione abbastanza carino per me, solo l'aggiunta di una variabile Swift come:

var myInstanceVar: String { 
    return self.value(forKey: "myInstanceVar") as! String 
} 
Problemi correlati