web-dev-qa-db-fra.com

Impossible d'accéder Swift 4 classe d'Objective-C: "Propriété non trouvée sur un objet de type"

En utilisant la dernière version bêta de Xcode 9, je suis apparemment totalement incapable d'accéder aux propriétés des classes Swift. Même plus étrange, je peux accéder à la classe elle-même pour l'instancier ou quoi que ce soit, mais complètement incapable d'accéder aux propriétés dessus.

Donc, si j'ai ceci Swift classe:

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.

50
Doug Smith

Les règles pour exposer Swift le code en Objective-C ont changé en Swift 4. Essayez ceci à la place:

@objc var foobar = true

En optimisation, les inférences @objc Ont été réduites dans Swift 4. Par exemple, une propriété dans une classe dérivée NSObject, telle que votre TestViewController, non ne déduira plus @objc par défaut (comme dans Swift 3 ).

Alternativement, vous pouvez également exposer tous les membres à Objective-C à la fois en utilisant @objcMembers:

@objcMembers class TestViewController: UIViewController {
    ...
}

La nouvelle conception est entièrement détaillée dans la proposition correspondante Swift Evolution .

126
Paulo Mattos

Swift 3.2/4.0/XCode 9.1

Vous définissez Swift3.2 dans les paramètres du projet ( //: configuration = Debug Swift_VERSION = 3.2)

vous pouvez utiliser votre code (utilisez le fichier d'importation correct dans objc, voir ci-dessous). Si vous définissez le projet sur Swift 4.0 ( //: configuration = Debug Swift_VERSION = 4.0)

Vous devez ajouter @objc à chaque propriété.

Alors:

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;
}

travaux.

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: le compilateur a échoué:

/Users....ViewController.m:24:21: La propriété 's1' est introuvable sur l'objet de type 'MyClass *'

comme s1 n'est pas ajouté avec @objc.

Vous devez écrire:

@objc class MyClass: NSObject{

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

(Remarque: dans le fichier C/C++/ObJC, placez toujours les fichiers system/general * h avant les en-têtes de classe "locaux".)

Swift 4

ajoutez simplement @objcMembers avant class @ objcMembers class MyClassObject: NSObject {var s1: String! var s2: String!

} Swift evolution entrez la description du lien ici

12
ingconti
  1. Lorsque vous ajoutez un fichier Swift dans votre projet Objective-C, Xcode vous invitera à ajouter un en-tête de pontage Objective-C, laissez donc le fichier d'en-tête être établi.
  2. Dans votre fichier d'implémentation Objective-C où vous souhaitez accéder à la propriété TestViewController foobar. Utilisez la syntaxe d'importation suivante et remplacez le Nom du projet par votre projet.

#import "ProjectName-Swift.h"

Fichier d'implémentation d'Objective-C:

#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, passez par Documents Apple

1
Rahul Kumar

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 en 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.

0
Prabhat Kasera