访问 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.
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"
我开始在我的视图控制器上编写 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.
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"