如何从 Swift 扩展访问 Objective-C 类的私有成员?

Posted

技术标签:

【中文标题】如何从 Swift 扩展访问 Objective-C 类的私有成员?【英文标题】:How to access private members of an Objective-C class from a Swift extension? 【发布时间】:2014-10-26 12:20:25 【问题描述】:

我正在尝试在 Swift 中扩展一个 Objective-C 类并使其符合Equatable 协议。这需要访问扩展类的一些 private 成员,编译器不允许我这样做。不公开私人成员的正确方法是什么?

我的 Swift 代码:

import Foundation

extension ShortDate : Equatable   

public func == (lhs: ShortDate, rhs: ShortDate) -> Bool 
    if (lhs.components.year == rhs.components.year)
        && (lhs.components.month == rhs.components.month)
        && (lhs.components.day == rhs.components.day) 
            return true;
    
    return false;

目标-C:

@interface ShortDate : NSObject<NSCopying, NSCoding> 
    NSDate           *inner;
    NSDateComponents *components; // The date split into components.


...

@end

我得到的错误:

ShortDate.swift:26:9: 'ShortDate' 没有名为 'components' 的成员

【问题讨论】:

您是否在 Swift 标头中添加了正确的标头:YourAppName-Bridging-Header.h 是的,当然,桥接头已经到位,我可以在我的 Swift 代码中使用 ShortDate 类。我只是想使用运算符而不是成员函数来添加比较。 【参考方案1】:

我在尝试找到一种从我们使用的 SDK 访问类的私有变量的方法时遇到了这个问题。由于我们没有或控制源代码,我们无法将变量更改为属性。我确实发现以下解决方案适用于这种情况:

extension ObjcClass 
    func getPrivateVariable() -> String? 
        return value(forKey: "privateVariable") as? String
    

    open override func value(forUndefinedKey key: String) -> Any? 
        if key == "privateVariable" 
            return nil
        
        return super.value(forUndefinedKey: key)
    

覆盖value(forUndefinedKey:) 是可选的。如果类中不存在私有变量,value(forKey:) 将崩溃,除非您覆盖 value(forUndefinedKey:) 并提供默认值。

【讨论】:

【参考方案2】:

我相信没有办法从 Swift 访问 Objective-C 实例变量。只有 Objective-C 属性被映射到 Swift 属性。

【讨论】:

看起来像那样。我用属性解决了它。

以上是关于如何从 Swift 扩展访问 Objective-C 类的私有成员?的主要内容,如果未能解决你的问题,请参考以下文章

UIColor swift 扩展,带有来自 Objective-C 的类访问

如何从同一个故事板访问 Objective-C 和 Swift 类?

如何从 Swift 单元测试访问测试目标中存在的 Objective-C 代码?

无法访问扩展 Objective-C 类的 Swift 类中的私有变量

从 Swift 访问 Objective-C #define 常量

从 Objective C 调用 Swift 中定义的 NSString 扩展