访问 Swift 扩展文件中的 Obj-C 属性

Accessing Obj-C properties in Swift extension file

我开始在我的视图控制器上编写 Swift 扩展。所以我现在有三个文件:

我的头文件,ViewController.h:

@interface MyViewController : UIViewController

@end

我的Obj-C实现文件,ViewController.m:

@interface MyViewController () <UIScrollViewDelegate>
@property (strong, nonatomic) UIScrollView *scrollView;
@end

@implementation MyViewController

- (void)viewDidLoad {

    [super viewDidLoad];

    self.scrollView = [[UIScrollView alloc] init];
    [self customiseScrollView]; //This is Swift method called from Obj-C file
}

@end

最后,ViewController.swift

extension MyViewController {

    func customiseScrollView() {

    }
}

我的问题是,是否可以从我的 Swift 实现文件访问我的 Obj-C 属性?每次引用都报错:

Value of type 'MyViewController' has no member 'scrollView'

奖励 1:有人还可以澄清 Swift 组件是否也可以看到 .m 是什么的委托。 (澄清一下,在 Swift 中执行 scrollView.delegate = self 是一个编译错误,因为 Swift 文件没有意识到 .m 文件是 UIScrollViewDelegate)。

奖励 2:Swift 扩展文件可以调用从 .m 副本声明的 Obj-C 方法吗?

可以。您只需要创建一个桥接 objective C header.

根据 Apple Documentation:

To import a set of Objective-C files in the same app target as your Swift code, you rely on an Objective-C bridging header to expose those files to Swift. Xcode offers to create this header file when you add a Swift file to an existing Objective-C app, or an Objective-C file to an existing Swift app.

只需创建一个 Bridging-Header 文件,然后在其中导入您的 ObjC 文件,例如:

#import <objectivec.h>

稍后在您的 swift 文件中:

var a = objectivec()
a.method_from_those_file

有关更多信息,请阅读 here 中的 Apple 文档。

我认为您无法从扩展访问私有属性。您的 scrollView 属性 在 .m 文件中,而不是 .h - 这意味着它是私有的并且在扩展文件中不可见。

解决方案:移动

@property (strong, nonatomic) UIScrollView *scrollView;

到你的头文件。

在 Swift 中,无法从另一个文件访问私有属性。这就是Swift中private的意思。例如:

file1.swift

class MyClass {
    private var privateProperty: String = "Can't get to me from another file!"
}
extension MyClass: CustomStringConvertible {
    var description: String {
        return "I have a `var` that says: \(privateProperty)"
    }
}

file2.swift

extension MyClass {
    func cantGetToPrivateProperties() {
        self.privateProperty // Value of type 'MyClass' has no memeber 'privateProperty'
    }
}

A 属性 在 Objective-C class 的实现中声明为私有 属性。因此,无法从 Swift 扩展访问 属性,因为这必然来自不同的 (.swift) 文件...

如果您在单独的 header 中声明 objc class 扩展并将 header 包含在桥接 header 中,则您可以访问内部 objc 属性和方法。

MyClass.h

@interface MyClass : NSObject

@property (nonatomic, copy, readonly) NSString *string;

@end

MyClass+Private.h

#import "MyClass.h"

@interface MyClass ()

@property (nonatomic, copy) NSString *string;

@end

MyClass.m

#import "MyClass+private.h"

@implementation MyClass

//...

@end

Project-Bridging-Header.h

#import "MyClass.h"
#import "MyClass+Private.h"