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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45656671/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 09:23:24  来源:igfitidea点击:

Unable to access Swift 4 class from Objective-C: "Property not found on object of type"

iosobjective-cswiftxcodeswift4

提问by Doug Smith

Using the latest Xcode 9 beta, I'm seemingly completely unable to access properties on Swift classes. Even odder, I can access the class itself to instantiate it or whatever, but completely unable to access properties on it.

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

So if I have this Swift class:

所以如果我有这个 Swift 类:

import UIKit

class TestViewController: UIViewController {
    var foobar = true
}

And I try to do this:

我尝试这样做:

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

What exactly am I doing wrong? New project with Xcode 9.

我到底做错了什么?使用 Xcode 9 的新项目。

回答by Paulo Mattos

The rules for exposing Swift code to Objective-C have changed in Swift 4. Try this instead:

将 Swift 代码暴露给 Objective-C 的规则在 Swift 4 中发生了变化。试试这个:

@objc var foobar = true

As an optimization, @objcinference have been reduced in Swift 4. For instance, a property within an NSObject-derived class, such as your TestViewController, will nolonger infer @objcby default (as it did in Swift 3).

作为一种优化,@objc推断已在斯威夫特4.减少举例来说,财产的范围内NSObject派生类,如你TestViewController,会不会再想见@objc在默认情况下(因为它在斯威夫特3一样)。

Alternatively, you could also expose allmembers to Objective-C at once using @objcMembers:

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

@objcMembers class TestViewController: UIViewController {
    ...
}

This new design is fully detailed in the corresponding Swift Evolution proposal.

这个新设计在相应的 Swift Evolution 提案中有完整的细节。

回答by ingconti

Swift 3.2/4.0 / XCode 9.1

斯威夫特 3.2/4.0 / XCode 9.1

You you set swift3.2 in project settings ( //:configuration = Debug SWIFT_VERSION = 3.2)

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

you can use your code,(using the correct import file in objc, see below). If You set project to swift 4.0 ( //:configuration = Debug SWIFT_VERSION = 4.0)

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

You must prepend @objc for every property.

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

So:

所以:

Swift 3.2:

斯威夫特 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;
}

works.

作品。

Swift 4.0:

斯威夫特 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;
}

does NOT works: compiler fails:

不起作用:编译器失败:

/Users....ViewController.m:24:21: Property 's1' not found on object of type 'MyClass *'

/Users....ViewController.m:24:21: 在“MyClass *”类型的对象上找不到属性“s1”

as s1 is not prepended with @objc.

因为 s1 前面没有@objc。

You must write:

你必须写:

@objc class MyClass: NSObject{

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

(As a side-note: in C/C++/ObJC file, put always system/general *h files before your "local" class headers.)

(附带说明:在 C/C++/ObJC 文件中,始终将 system/general *h 文件放在“本地”类头文件之前。)

Swift 4

斯威夫特 4

just add @objcMembers before class @objcMembersclass MyClassObject: NSObject { var s1: String! var s2: String!

只需在@objcMembers类之前添加 @objcMembers 类 MyClassObject: NSObject { var s1: String! var s2:字符串!

} Swift evolutionenter link description here

Swift 进化在这里输入链接描述

回答by protspace

As for Swift 5.1 I found that "@objc" is not enough, but also make it public "@objc public":

至于Swift 5.1,我发现“@objc”还不够,还要公开“@objc public”:

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

回答by Rahul Kumar

  1. When you add a swift file in your Objective-C project, Xcode will prompt to add Objective-C bridging headerfile, so allow the header file to be created.
  2. In your Objective-C implementation file where you want to access the TestViewController property foobar. Use the following import syntax and replace the ProjectName with your project.
  1. 当您在 Objective-C 项目中添加 swift 文件时,Xcode 会提示添加Objective-C 桥接头文件,因此允许创建头文件。
  2. 在您想要访问 TestViewController 属性foob​​ar 的Objective-C 实现文件中。使用以下导入语法并将 ProjectName 替换为您的项目。

#import "ProjectName-Swift.h"

#import "ProjectName-Swift.h"

Objective-C implementation file:

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

For more details go through the Apple Documents

有关更多详细信息,请参阅Apple 文档

回答by P Anandhakumar

Xcode 10.2 | Swift 4Adding @objcMembersbefore class solved my problem.

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

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

回答by Prabhat Kasera

I also encountered with this problem in swift 3.0

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

class declaration was like that

类声明就是这样

class ClassA {
//statements
}

above class was not accessible in Objective C code and it was also not registered in -Swift.h

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

once I inherited from NSObject like this:

一旦我像这样从 NSObject 继承:

class ClassA : NSObject {
//statements
} 

the class was accessible in Objective c and got registered with -Swift.h

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

This solution is useful when you don't want to avoid inheritance from NSobject class.

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