2016-02-06 13 views
8

Sto miscelando e abbinando correttamente Obj-C e Swift in un progetto Xcode 7. Tuttavia, non riesco a capire come, in una classe Objective C, ereditare da una classe Swift (e sì, so dichiarare che la classe Swift come @objc per la visibilità). In questo caso la superclasse Swift desiderata MySwiftViewController è una sottoclasse di UIViewController. Per ora, in Obj-C, sto ereditando direttamente da UIViewController e non ottenendo l'accesso alle funzionalità che ho aggiunto in MySwiftViewController.Eredita da una classe Swift nell'obiettivo C

Ecco quello che ho capito:

- per dichiarare una classe Obj-C come ereditare da qualcosa, che deve essere nel file h dopo il ':':

#import <UIKit/UIKit.h> 
@interface RootViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> 
@end 

- per rendere le classi Swift visibile, cioè #import ndr:

#import "MyProject-Swift.h" 

Tuttavia, non è possibile importare la Swift auto-generata intestazione colmare in Obj-C .h file. Non è inoltre possibile inoltrare una superclasse opaca con @class. Quindi, è possibile e come?

risposta

20

Sfortunatamente, non è possibile creare una sottoclasse di una classe Swift in Objective-C. Direttamente dai documenti:

Non è possibile sottoclasse una classe Swift in Objective-C.

Vedere Apple guide on interoperability per ulteriori dettagli su cosa è possibile e impossibile accedere con Objective-C.

+0

Ecco il link alla documentazione - https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/Migration.html – david72

3

Come per Xcode 8.0 e versioni precedenti c'è una soluzione dirty-hacky, che probabilmente verrà risolta in futuro.

Se si desidera sottoclasse da file rapido, è possibile aggiungere l'attributo objc_subclassing_restricted. Puoi renderlo come macro per comodità. Codice:

Classe Swift.

import Foundation 

class SwiftClass : NSObject { 
    func say() { 
    print("hi"); 
    } 
} 

classe objc:

#import <Foundation/Foundation.h> 

#import "test-Swift.h" 

#define SWIFT_SUBCLASS __attribute__((objc_subclassing_restricted)) 

SWIFT_SUBCLASS 
@interface ObjcClass : SwiftClass 
- (instancetype)init; 
@end 
@implementation ObjcClass 
- (void)say { 
    NSLog(@"oops"); 
} 
@end 

Ma, a quanto ho capito, non è supportato, e si può avere alcun tipo di bug a causa di esso. Quindi non è una guida all'azione, e qualcosa di più curioso da sapere.

+0

Posso confermare che questa soluzione alternativa viene compilata correttamente su Xcode 8.1 ma il la classe non c'è, quindi la compilazione fallisce nella fase di linker. –

+0

Puoi fornire un esempio più specifico? Ho appena creato ed eseguito sopra il codice su Xcode 8.2.1. Funziona bene, e ancora più '[[ObjcClass alloc] init] dice]' stampa "oops" senza errori. –

+0

Non funziona per me su Xcode 8.3.2. Ottieni l'errore "can not subclass" sulla riga '@ implementation' (senza __attribute__, lo prendo già sulla riga' @ interface') – ernesto