无法从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”文件放在“本地”类标题之前。)
- 在Objective-C项目中添加swift文件时,Xcode将提示添加Objective-C桥接头文件,因此允许创建头文件。
- 在Objective-C实现文件中,您要访问TestViewController属性foobar 。 使用以下导入语法并将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时,此解决方案很有用。