使用最新的Xcode 9 beta,我似乎完全无法访问Swift类的属性。甚至更奇怪,我可以访问类本身来实例化它或其他任何东西,但完全无法访问它上面的属性。
所以如果我有这个Swift类:
import UIKit
class TestViewController: UIViewController {
var foobar = true
}
我尝试这样做:
TestViewController *testViewController = [[TestViewController alloc] init]; // success
testViewController.foobar; // error
我究竟做错了什么?使用Xcode 9的新项目。
答案 0 :(得分:108)
将Swift代码暴露给Objective-C的规则在Swift 4中已经改变。试试这个:
@objc var foobar = true
作为优化,在Swift 4中减少了@objc
推理。例如,NSObject
派生类中的属性(例如TestViewController
)将否默认情况下推断@objc
更长(就像在Swift 3中一样)。
或者,您也可以使用@objcMembers
一次将所有成员公开给Objective-C:
@objcMembers class TestViewController: UIViewController {
...
}
答案 1 :(得分:9)
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 *'类型的对象上找不到属性'1'
因为s1没有附加@objc。
你必须写:
@objc class MyClass: NSObject{
@objc var s1: String?
@objc var s2 : String?
}
(作为旁注:在C / C ++ / ObJC文件中,将“system”/ general * h文件放在“本地”类标题之前。)
Swift 4
在上课前添加@objcMembers @objcMembers 类MyClassObject:NSObject { var s1:String! var s2:String!
答案 2 :(得分:2)
对于Swift 5.1,我发现“ @objc”是不够的,但是将其公开为“ @objc public”:
@objc public class SomeClass: NSObject {
@objc public let amount: NSNumber
...
答案 3 :(得分:1)
#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 Documents
答案 4 :(得分:0)
我在Swift 3.0中也遇到了这个问题
类声明就是这样
class ClassA {
//statements
}
以上类无法在Objective C代码中访问,并且也未在-Swift.h中注册
一旦我像这样从NSObject继承:
class ClassA : NSObject {
//statements
}
该类可在目标c中访问,并已在-Swift.h中注册
当您不想避免从NSobject类继承时,此解决方案很有用。
答案 5 :(得分:-1)
Xcode 10.2 |斯威夫特4
在上课前添加@objcMembers
解决了我的问题。
@objcMembers class MyClass:NSObject {
var s1: String!
var s2: NSMutableArray!
}