69 votes

Impossible d'accéder à la classe Swift 4 à partir d'Objective-C: "Propriété introuvable sur l'objet de type"

Avec la dernière version bêta de Xcode 9, je suis apparemment totalement incapable d'accéder aux propriétés des classes Swift. Encore plus étrange, je peux accéder à la classe elle-même pour l'instancier ou quoi que ce soit, mais je ne peux absolument pas accéder aux propriétés qu'elle contient.

Donc, si j'ai cette classe Swift:

 import UIKit

class TestViewController: UIViewController {
    var foobar = true
}
 

Et j'essaie de faire ceci:

 TestViewController *testViewController = [[TestViewController alloc] init]; // success
testViewController.foobar; // error
 

Qu'est-ce que je fais exactement mal? Nouveau projet avec Xcode 9.

172voto

Paulo Mattos Points 10791

Les règles pour exposer Swift code Objective-C ont changé dans Swift 4. Essayez plutôt ceci:

@objc var foobar = true

Comme une optimisation, @objc d'inférence ont été réduits en Swift 4. Par exemple, une propriété à l'intérieur d'un NSObject-classe dérivée, comme votre TestViewController, sera de ne plus déduire @objc par défaut (comme il l'a fait dans Swift 3).

Sinon, vous pouvez également exposer tous les membres d'Objective-C à la fois à l'aide de @objcMembers:

@objcMembers class TestViewController: UIViewController {
    ...
}

Le nouveau design est entièrement détaillée dans le correspondant Swift Évolution de la proposition.

13voto

ingconti Points 405

Swift 3.2/4.0 / XCode 9.1

Vous vous définissez swift3.2 dans les paramètres de projet ( //:configuration = Debug SWIFT_VERSION = 3.2 )

vous pouvez utiliser votre code(en utilisant le bon fichier d'importation en objc, voir ci-dessous). Si Vous définissez projet swift 4.0 ( //:configuration = Debug SWIFT_VERSION = 4.0 )

Vous devez préfixer @objc pour chaque propriété.

Donc:

Swift 3.2:

// MyClass.swift

@objc class MyClass: NSObject{

    var s1: String?
    @objc var s2 : String?
}


//

//  ViewController.m

import "MixingObjCAndSwift-Swift.h"
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];        
    MyClass * mc = [MyClass new];
    NSString * s1 = mc.s1;
    NSString * s2 = mc.s2;
}

des œuvres.

Swift 4.0:

// MyClass.swift

@objc class MyClass: NSObject{

    var s1: String?
    @objc var s2 : String?
}


.....  
- (void)viewDidLoad {
    [super viewDidLoad];        
    MyClass * mc = [MyClass new];
    NSString * s1 = mc.s1;
    NSString * s2 = mc.s2;
}

ne fonctionne PAS: compilateur échoue:

/Utilisateurs....ViewController.m:24:21: Propriété 's1' ne trouve pas sur l'objet de type " Maclasse *'

s1 n'est pas précédé de @objc.

Vous devez écrire:

@objc class MyClass: NSObject{

    @objc var s1: String?
    @objc var s2 : String?
}

(Une-remarque: en C/C++/ObJC fichier, mettez toujours le système/général *h fichiers avant "local" de la classe en-têtes.)

Swift 4

juste ajouter @objcMembers avant la classe @objcMembers classe MyClassObject: NSObject { var s1: Chaîne! var s2: Chaîne!

} Swift évolutionentrez description du lien ici

2voto

Rahul Kumar Points 802
  1. Lorsque vous ajoutez un swift de fichier dans votre Objective-C, Xcode, vous invite à ajouter Objective-C de transition de l'en-tête de fichier, afin de permettre à l'en-tête de fichier à créer.
  2. Dans votre Objectif-C mise en œuvre de fichier où vous voulez accéder à la TestViewController propriété foobar. Utiliser la suite de l'importation de la syntaxe et de remplacer le ProjectName avec votre projet.

#import "ProjectName-Swift.h"

Objective-C fichier de mise en oeuvre:

#import "ViewController.h"
#import "ProjectName-Swift.h"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    TestViewController *testViewController = [[TestViewController alloc] init]; // success
    BOOL prop = testViewController.foobar;
    NSLog(@"Property: %d", prop);
}

@end

Pour plus de détails, allez par le biais de la Pomme de Documents

2voto

P Anandhakumar Points 3

Xcode 10.2 | Swift 4 Ajouter @objcMembers avant le cours a résolu mon problème.

 @objcMembers class MyClass:NSObject {
   var s1: String!
   var s2: NSMutableArray!
}
 

0voto

balla Points 427

J'ai aussi rencontré ce problème dans swift 3.0

déclaration de classe était comme ça

 class ClassA {
//statements
}
 

la classe ci-dessus n'était pas accessible dans le code Objective C et n'était pas non plus enregistrée dans -Swift.h

Une fois, j'ai hérité de NSObject comme ceci:

 class ClassA : NSObject {
//statements
} 
 

la classe était accessible dans Objective c et s'est inscrite avec -Swift.h

Cette solution est utile lorsque vous ne voulez pas éviter l'héritage de la classe NSobject.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X