Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/100.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 无法从Objective-C访问Swift 4类;在类型为“的对象上找不到属性”;_Ios_Objective C_Swift_Xcode_Swift4 - Fatal编程技术网

Ios 无法从Objective-C访问Swift 4类;在类型为“的对象上找不到属性”;

Ios 无法从Objective-C访问Swift 4类;在类型为“的对象上找不到属性”;,ios,objective-c,swift,xcode,swift4,Ios,Objective C,Swift,Xcode,Swift4,使用最新的Xcode 9测试版,我似乎完全无法访问Swift类的属性。更奇怪的是,我可以访问类本身来实例化它,但完全无法访问它的属性 因此,如果我有这个Swift课程: import UIKit class TestViewController: UIViewController { var foobar = true } 我试着这样做: TestViewController *testViewController = [[TestViewController alloc] init

使用最新的Xcode 9测试版,我似乎完全无法访问Swift类的属性。更奇怪的是,我可以访问类本身来实例化它,但完全无法访问它的属性

因此,如果我有这个Swift课程:

import UIKit

class TestViewController: UIViewController {
    var foobar = true
}
我试着这样做:

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

我到底做错了什么?使用Xcode 9的新项目。

在Swift 4中,向Objective-C公开Swift代码的规则已更改。请尝试以下方法:

@objc var foobar = true
作为一种优化,Swift 4中减少了
@objc
推理。例如,
NSObject
派生类中的属性,如
TestViewController
,在默认情况下将不再推断
@objc
(如Swift 3中所做)

或者,您也可以使用
@objcMembers
,将所有成员一次性公开给Objective-C:

@objcMembers class TestViewController: UIViewController {
    ...
}

这一新设计在中有详细说明。

在Swift 4中,将Swift代码公开给Objective-C的规则已经更改。请尝试以下方法:

@objc var foobar = true
作为一种优化,Swift 4中减少了
@objc
推理。例如,
NSObject
派生类中的属性,如
TestViewController
,在默认情况下将不再推断
@objc
(如Swift 3中所做)

或者,您也可以使用
@objcMembers
,将所有成员一次性公开给Objective-C:

@objcMembers class TestViewController: UIViewController {
    ...
}
这一新设计在中有详细说明

  • 在Objective-C项目中添加swift文件时,Xcode将提示添加Objective-C桥接头文件,以便创建头文件
  • 在您想要访问TestViewController属性foobar的Objective-C实现文件中。使用以下导入语法并用项目替换项目名称
  • #导入“ProjectName Swift.h”

    目标-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
    
    // 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;
    }
    
    // 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;
    }
    
    有关更多详细信息,请浏览

  • 在Objective-C项目中添加swift文件时,Xcode将提示添加Objective-C桥接头文件,以便创建头文件
  • 在您想要访问TestViewController属性foobar的Objective-C实现文件中。使用以下导入语法并用项目替换项目名称
  • #导入“ProjectName Swift.h”

    目标-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
    
    // 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;
    }
    
    // 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;
    }
    

    有关更多详细信息,请参阅Swift 3.2/4.0/XCode 9.1

    您可以在项目设置(//:configuration=Debug)中设置swift3.2 SWIFT_版本=3.2)

    您可以使用您的代码(使用objc中的正确导入文件,请参见下文)。 如果将项目设置为swift 4.0(//:配置=调试 SWIFT_版本=4.0)

    必须为每个属性预先设置@objc

    因此:

    Swift 3.2:

    #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
    
    // 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;
    }
    
    // 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;
    }
    
    工作

    Swift 4.0:

    #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
    
    // 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;
    }
    
    // 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;
    }
    
    不工作:编译器失败:

    /Users….ViewController.m:24:21:在“MyClass*”类型的对象上找不到属性“s1”

    因为s1前面没有@objc

    你必须写:

    @objc class MyClass: NSObject{
    
        @objc var s1: String?
        @objc var s2 : String?
    }
    
    (作为旁注:在C/C++/ObJC文件中,始终将system/general*h文件放在“local”类标题之前。)

    Swift 4

    只需在上课前添加@objcMembers即可 @objcMembers类MyClassObject:NSObject { 变量s1:字符串! var s2:字符串

    }
    快速发展

    Swift 3.2/4.0/XCode 9.1

    您可以在项目设置(//:configuration=Debug)中设置swift3.2 SWIFT_版本=3.2)

    您可以使用您的代码(使用objc中的正确导入文件,请参见下文)。 如果将项目设置为swift 4.0(//:配置=调试 SWIFT_版本=4.0)

    必须为每个属性预先设置@objc

    因此:

    Swift 3.2:

    #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
    
    // 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;
    }
    
    // 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;
    }
    
    工作

    Swift 4.0:

    #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
    
    // 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;
    }
    
    // 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;
    }
    
    不工作:编译器失败:

    /Users….ViewController.m:24:21:在“MyClass*”类型的对象上找不到属性“s1”

    因为s1前面没有@objc

    你必须写:

    @objc class MyClass: NSObject{
    
        @objc var s1: String?
        @objc var s2 : String?
    }
    
    (作为旁注:在C/C++/ObJC文件中,始终将system/general*h文件放在“local”类标题之前。)

    Swift 4

    只需在上课前添加@objcMembers即可 @objcMembers类MyClassObject:NSObject { 变量s1:字符串! var s2:字符串

    }
    Swift evolution

    我在Swift 3.0中也遇到了这个问题

    类声明是这样的

    class ClassA {
    //statements
    }
    
    上述类在目标C代码中无法访问,也未在-Swift.h中注册

    一旦我继承了NSObject,如下所示:

    class ClassA : NSObject {
    //statements
    } 
    
    该类可以在目标c中访问,并在-Swift.h中注册


    当您不想避免从NSobject类继承时,此解决方案非常有用。

    我在swift 3.0中也遇到过此问题

    类声明是这样的

    class ClassA {
    //statements
    }
    
    上述类在目标C代码中无法访问,也未在-Swift.h中注册

    一旦我继承了NSObject,如下所示:

    class ClassA : NSObject {
    //statements
    } 
    
    该类可以在目标c中访问,并在-Swift.h中注册


    当您不想避免从NSobject类继承时,此解决方案非常有用。

    Xcode 10.2 | Swift 4 上课前添加
    @objcMembers
    解决了我的问题

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

    Xcode 10.2 | Swift 4 上课前添加
    @objcMembers
    解决了我的问题

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

    至于Swift 5.1,我发现“@objc”是不够的,还要公开“@objc public”:


    至于Swift 5.1,我发现“@objc”是不够的,还要公开“@objc public”:


    比较我仍然面临从Swift到objective-C访问Int&Bool属性的问题。。。获取此错误:属性不能标记为@objc,因为它的类型不能在Objective-C中表示,Any suggetion。。我使用了标题“MyProject-Swift.hOnly字符串属性是可访问的