Unable to access Swift 4 class from Objective-C: “Property not found on object of type”

后端 未结 6 569
南笙
南笙 2020-12-04 18:55

Using the latest Xcode 9 beta, I\'m seemingly completely unable to access properties on Swift classes. Even odder, I can access the class itself to instantiate it or whateve

相关标签:
6条回答
  • 2020-12-04 19:21

    I also encountered with this problem in swift 3.0

    class declaration was like that

    class ClassA {
    //statements
    }
    

    above class was not accessible in Objective C code and it was also not registered in -Swift.h

    once I inherited from NSObject like this:

    class ClassA : NSObject {
    //statements
    } 
    

    the class was accessible in Objective c and got registered with -Swift.h

    This solution is useful when you don't want to avoid inheritance from NSobject class.

    0 讨论(0)
  • 2020-12-04 19:27

    Xcode 10.2 | Swift 4 Adding @objcMembers before class solved my problem.

    @objcMembers class MyClass:NSObject {
       var s1: String!
       var s2: NSMutableArray!
    }
    
    0 讨论(0)
  • 2020-12-04 19:28

    Swift 3.2/4.0 / XCode 9.1

    You you set swift3.2 in project settings ( //:configuration = Debug SWIFT_VERSION = 3.2 )

    you can use your code,(using the correct import file in objc, see below). If You set project to swift 4.0 ( //:configuration = Debug SWIFT_VERSION = 4.0 )

    You must prepend @objc for every property.

    So:

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

    works.

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

    does NOT works: compiler fails:

    /Users....ViewController.m:24:21: Property 's1' not found on object of type 'MyClass *'

    as s1 is not prepended with @objc.

    You must write:

    @objc class MyClass: NSObject{
    
        @objc var s1: String?
        @objc var s2 : String?
    }
    

    (As a side-note: in C/C++/ObJC file, put always system/general *h files before your "local" class headers.)

    Swift 4

    just add @objcMembers before class @objcMembers class MyClassObject: NSObject { var s1: String! var s2: String!

    } Swift evolutionenter link description here

    0 讨论(0)
  • 2020-12-04 19:28

    As for Swift 5.1 I found that "@objc" is not enough, but also make it public "@objc public":

    @objc public class SomeClass: NSObject {
        @objc public let amount: NSNumber
    ...
    
    0 讨论(0)
  • 2020-12-04 19:38
    1. When you add a swift file in your Objective-C project, Xcode will prompt to add Objective-C bridging header file, so allow the header file to be created.
    2. In your Objective-C implementation file where you want to access the TestViewController property foobar. Use the following import syntax and replace the ProjectName with your project.

    #import "ProjectName-Swift.h"

    Objective-C implementation file:

    #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
    

    For more details go through the Apple Documents

    0 讨论(0)
  • 2020-12-04 19:44

    The rules for exposing Swift code to Objective-C have changed in Swift 4. Try this instead:

    @objc var foobar = true
    

    As an optimization, @objc inference have been reduced in Swift 4. For instance, a property within an NSObject-derived class, such as your TestViewController, will no longer infer @objc by default (as it did in Swift 3).

    Alternatively, you could also expose all members to Objective-C at once using @objcMembers:

    @objcMembers class TestViewController: UIViewController {
        ...
    }
    

    This new design is fully detailed in the corresponding Swift Evolution proposal.

    0 讨论(0)
提交回复
热议问题