Ios 无法从Objective-C访问Swift 4类;在类型为“的对象上找不到属性”;
使用最新的Xcode 9测试版,我似乎完全无法访问Swift类的属性。更奇怪的是,我可以访问类本身来实例化它,但完全无法访问它的属性 因此,如果我有这个Swift课程: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
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 {
...
}
这一新设计在中有详细说明
#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;
}
有关更多详细信息,请浏览
#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字符串属性是可访问的