如何在 Swift 子类中引用目标 c 实例变量?

Posted

技术标签:

【中文标题】如何在 Swift 子类中引用目标 c 实例变量?【英文标题】:How to refer to objective c instance variable in Swift subclass? 【发布时间】:2019-09-08 13:40:07 【问题描述】:

我有一个扩展目标 c 类的层次结构。 然后我创建了一个扩展目标 c 类的 swift 类。 在桥接头文件中,我添加了父类(它是 Objective c)。所以继承没问题,但我无法访问超类属性。

@interface ObjectivecViewController : ExtendedUIViewController
    
     IBOutlet UIView *view1;
 
//----------------------------------------
import Foundation
import UIKit

class SwiftViewController : ObjectivecViewController 

    override func viewDidLoad() 
        view1 -----> I cannot access view1 here. but if the class was objective c I could.

    
 

我可以访问超类属性,但是当我将其定义为实例变量时,我无法访问它

我什至将 view1 更改为受保护的变量,但我仍然无法引用它

【问题讨论】:

您可以添加代码吗?这样可以很容易地检查出问题所在。 您必须添加代码让我们帮助您。因为大多数问题是由于错过了一些非常小但非常重要的部分,最终导致了问题。 @AbdulRaheemBeigh MoinuddinGirach 谢谢,我编辑了它 【参考方案1】:

只有 Objective C 属性被导出到 Swift。实例变量对 Swift 是不可见的。

见:Accessing Objective-c base class's instance variables from a Swift class

【讨论】:

【参考方案2】:

除了@Gunter 引用的线程中提供的一些好主意,这里还有另一种方法。您可以在ObjectivecViewController 上创建一个类别,并通过自定义访问器方法添加一个由view1 实例变量支持的属性。

ObjectivecViewController+ViewProperty.h:

#import "ObjectivecViewController.h"

@interface ObjectivecViewController (ViewProperty)

@property UIView * view1; // I would use a different name for the property
                          // to avoid confusion, though...
// Getter and setter
-(UIView*)view1;
-(void)setView1:(UIView * _Nonnull)view_1;

@end

它的实现:

#import "ObjectivecViewController+ViewProperty.h"

@implementation ObjectivecViewController (ViewProperty)

-(UIView*)view1 
    return self->view1;


-(void)setView1:(UIView * _Nonnull)view_1 
    self->view1 = view_1;


@end

然后在您的桥接头中导入ObjectivecViewController+ViewProperty.h。现在您的 Swift 类应该能够使用继承的 view1 属性,该属性由 Objective-C 超类中同名的实例变量支持(同样,我会为属性和实例变量使用不同的名称......) .

由于您似乎能够修改 ObjectivecViewController 的来源,因此您可以只在其中添加属性而不是在类别中。

希望这会有所帮助。或者您是否试图避免使用属性来隐藏外部代码中的视图或出于其他原因?

【讨论】:

【参考方案3】:

也许你可以使用带有 ValueForKey 的变量名来访问它

self.valueForKey("变量名")

【讨论】:

【参考方案4】:

我建议您从 .m 文件中删除 IBOutlet UIView *view1; 并声明一个@property (weak, nonatomic) IBOutlet UIView *view1; 你的 .h 文件。

您确实应该在ObjectivecViewController 头文件中将您的UIView *view1; 声明为一个属性,以便能够从子视图控制器访问它。它不再是私有的,但它会起作用。

即使您从另一个 objc 类继承了一个 objc 类,从父级访问 Objective-C 私有属性也一直是个问题。

【讨论】:

以上是关于如何在 Swift 子类中引用目标 c 实例变量?的主要内容,如果未能解决你的问题,请参考以下文章

JAVA中如何对父类对象强制转换子类对象的引用

在目标 C 中引用另一个类中的实例化对象

尽管桥接头工作正常,但无法在 Swift 中实例化 Obj C 类

python 面向程序编程

如何在 swift 中将子类 NSManagedObject 分配给 var(而不是常量)

如何在 Swift 中识别强引用循环?