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

使用最新的Xcode 9 beta,我似乎完全无法访问Swift类的属性。 甚至更奇怪,我可以访问类本身来实例化它或其他什么,但完全无法访问它的属性。

所以如果我有这个Swift类:

import UIKit class TestViewController: UIViewController { var foobar = true } 

我试着这样做:

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

我究竟做错了什么? Xcode 9的新项目。

在Swift 4中将Swift代码暴露给Objective-C的规则已经改变了。试试这个:

 @objc var foobar = true 

作为优化,在Swift 4中已经减少了@objc推断。例如, NSObject派生类中的属性(例如TestViewController )将不再默认推断@objc (就像在Swift 3中那样)。

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

 @objcMembers class TestViewController: UIViewController { ... } 

新设计在相应的Swift Evolution提案中有详细说明。

Swift 3.2 / 4.0 / XCode 9.1

你在项目设置中设置了swift3.2( //:configuration = Debug SWIFT_VERSION = 3.2

你可以使用你的代码,(在objc中使用正确的导入文件,见下文)。 如果您将项目设置为swift 4.0( //:configuration = Debug SWIFT_VERSION = 4.0

您必须为每个属性添加@objc。

所以:

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

作品。

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

不起作用:编译器失败:

/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”文件放在“本地”类标题之前。)

  1. 在Objective-C项目中添加swift文件时,Xcode将提示添加Objective-C桥接头文件,因此允许创建头文件。
  2. 在Objective-C实现文件中,您要访问TestViewController属性foob​​ar 。 使用以下导入语法并将ProjectName替换为您的项目。

#import“ProjectName-Swift.h”

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 

有关详细信息,请浏览Apple文档

我在swift 3.0中也遇到过这个问题

类声明就是这样

 class ClassA { //statements } 

在Objective C代码中无法访问上面的类,它也没有在-Swift.h中注册

一旦我从NSObjectinheritance了这样的:

 class ClassA : NSObject { //statements } 

该类可以在Objective c中访问,并在-Swift.h中注册

当您不想避免从NSobject类inheritance时,此解决方案很有用。