Impossible d'accéder à la propriété de type Swift à partir de Objective-C

J'essaie d'invoquer un var de swift de la class objective c. Ce que je fais comme ci-dessous:

Classe Swift

class BusinessDetailViewController: UIViewController { var lat : Double? var lon : Double? @IBOutlet var mapView: MKMapView? override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } override init(nibName nibNameOrNil: Ssortingng?, bundle nibBundleOrNil: NSBundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) // Here you can init your properties } required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } 

À ViewController.m, j'essaye d'invoquer lat comme suit:

 #import "i5km-Swift.h" @interface ViewController () @property (strong, nonatomic) BusinessDetailViewController *businessDetailViewController; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. self.businessDetailViewController = [[BusinessDetailViewController alloc] initWithNibName:@"BusinessDetailViewController" bundle:nil]; self.businessDetailViewController.lat = businessArray[1]; /* THIS GIVES ME AN ERROR */ } 

et je reçois

 Property 'lat' not found on object of type 'BusinessDetailViewController *' 

Toutes les idées pour lesquelles je ne peux pas accéder ou il me manque quelque chose d'autre.

Les valeurs facultatives des types non-Objective-C ne sont pas reliées en Objective-C. Autrement dit, les trois premières propriétés de TestClass ci dessous seraient disponibles en Objective-C, mais la quasortingème ne serait pas:

 class TestClass: NSObject { var nsNumberVar: NSNumber = 0 // obj-c type, ok var nsNumberOpt: NSNumber? // optional obj-c type, ok var doubleVar: Double = 0 // bridged Swift-native type, ok var doubleOpt: Double? // not bridged, inaccessible } 

Dans votre code Objective-C, vous accédez aux trois premières propriétés suivantes:

 TestClass *optTest = [[TestClass alloc] init]; optTest.nsNumberOpt = @1.0; optTest.nsNumberVar = @2.0; optTest.doubleVar = 3.0; 

Dans votre cas, vous pouvez convertir lat et long en non-Optional ou les changer en instances de NSNumber .


Notez que vous devez faire attention à votre code Objective-C si vous adoptez la seconde approche (basculer lat et lon vers des propriétés non-optionnelles de type NSNumber ) – tandis que le compilateur Swift vous empêchera d'affecter nil à des propriétés non optionnelles , le compilateur Objective-C n'a aucun scrupule à l'autoriser, laissant les valeurs nil se faufiler dans votre code Swift sans aucune chance de les attraper au moment de l'exécution. Considérez cette méthode sur TestClass :

 extension TestClass { func badIdea() { // print the ssortingng value if it exists, or 'nil' otherwise println(nsNumberOpt?.ssortingngValue ?? "nil") // non-optional: must have a value, right? println(nsNumberVar.ssortingngValue) } } 

Cela fonctionne correctement si invoqué avec des valeurs dans les deux propriétés, mais si nsNumberVar est défini sur nil partir du code Objective-C, cela se bloque au moment de l'exécution. Notez qu'il n'y a aucun moyen de vérifier si nsNumberVar est nil avant de l'utiliser!

 TestClass *optTest = [[TestClass alloc] init]; optTest.nsNumberOpt = @1.0; optTest.nsNumberVar = @2.0; [optTest badIdea]; // prints 1, 2 optTest.nsNumberOpt = nil; optTest.nsNumberVar = nil; [optTest badIdea]; // prints nil, then crashes with an EXC_BAD_ACCESS exception 

Si votre propriété est un type de protocole Swift, ajoutez simplement @objc devant celle-ci.

Exemple:

 class Foo: UIViewController { var delegate: FooDelegate? ... } @objc protocol FooDelegate { func bar() } 

Optionals est une fonction spécifique rapide, non disponible dans obj-c. Les instances de class optionnelles fonctionnent car un optionnel nil peut être mappé à une valeur nulle, mais les types de valeur (int, floats, etc.) ne sont pas des types de references, donc les variables ne stockent pas de reference, mais la valeur elle-même.

Je ne sais pas s'il existe une solution – une solution possible consiste à créer des propriétés non facultatives mappant la valeur nil à une valeur de type de données inutilisée (telle que -1 pour la représentation d'un index ou 999999 pour une coordonnée):

 class Test { var lat : Double? { didSet { self._lat = self.lat != nil ? self.lat! : 999999 } } var lon : Double? { didSet { self._lon = self.lon != nil ? self.lon! : 999999 } } var _lat: Double = 99999999 var _lon: Double = 99999999 } 

Cela devrait exposer les propriétés _lat et _lon à obj-c.

Notez que je n'ai jamais essayé cela, alors s'il vous plaît laissez-nous savoir si cela fonctionne.