无法从 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的新项目。

35920 次浏览

在 Swift 4中,将 Swift 代码暴露给 Objective-C 的规则已经改变:

@objc var foobar = true

作为一种优化,@objc推理在 Swift 4中得到了减少。例如,NSObject派生类中的属性,比如 TestViewController,在默认情况下,没有会推断出更长的 @objc(正如它在 Swift 3中所做的那样)。

或者,您也可以使用 @objcMembers立即将 所有成员暴露给 Objective-C:

@objcMembers class TestViewController: UIViewController {
...
}

这种新的设计是完全详细的 相应的迅速进化方案

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

# import“ 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

更多细节请浏览 苹果文件

Swift 3.2/4.0/XCode 9.1

您可以在项目设置(< em >//: configuration = Debug)中设置 Swift 3.2 斯威夫特公司(SWIFT)

您可以使用自己的代码(在 obc 中使用正确的导入文件,见下文)。 如果您将 project 设置为 Swift 4.0(< em >//: configuration = Debug SWIFT _ VERION = 4.0 )

必须为每个属性添加@objecc。

所以:

迅捷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: Property’s 1’not found on object of object of type‘ MyClass *’

因为 s1没有在@obc 前面加上。

你必须写:

@objc class MyClass: NSObject{


@objc var s1: String?
@objc var s2 : String?
}

(作为附注: 在 C/C + +/ObJC 文件中,总是将 system/general * h 文件放在“ local”类头之前。)

斯威夫特

只要在上课前添加@objeccMember 即可 类 MyClassObject: NSObject { Var s1: String! Var s2: String!

} 快速进化在这里输入链接描述

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

类声明就是这样的

class ClassA {
//statements
}

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

一旦我继承了 NSObject 就像这样:

class ClassA : NSObject {
//statements
}

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

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

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

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

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

@objc public class SomeClass: NSObject {
@objc public let amount: NSNumber
...