【问题标题】:How do I access private instance variables in Obj-C or Swift?如何在 Obj-C 或 Swift 中访问私有实例变量?
【发布时间】:2023-04-02 16:33:01
【问题描述】:

我正在尝试在 macOS 上的 Swift 中访问 MKMapSnapshotter 的私有实例变量 _lodpiSnapshotCreator_hidpiSnapshotCreator

感谢 class-dump,我知道他们在那里 (see here):

@interface MKMapSnapshotter : NSObject
{
    [...]
    VKMapSnapshotCreator *_lodpiSnapshotCreator;
    VKMapSnapshotCreator *_hidpiSnapshotCreator;
}

但无论我做什么,我都无法抓住它们。

这是我检查是否可以访问它们的方式:

let snapshotter = MKMapSnapshotter(options: snapshotOptions)

let varNames = ["_lodpiSnapshotCreator", "_hidpiSnapshotCreator"]
for varName in varNames {
    if let testIVar = class_getInstanceVariable(MKMapSnapshotter.self, varName) {
        if let test = object_getIvar(snapshotter, testIVar) as? VKMapSnapshotCreator {
            print(test)
        } else {
            print("Got ivar, but \(varName) is still nil (getInstanceVariable)")
        }
    } else {
        print("\(varName) is nil (getInstanceVariable)")
    }
}

奇怪的是,class_getInstanceVariable 不会返回 nil,但 object_getIvar 会。

Got ivar, but _lodpiSnapshotCreator is still nil (getInstanceVariable)
Got ivar, but _hidpiSnapshotCreator is still nil (getInstanceVariable)

我在这里束手无策。我可以通过 Google 找到的只是人们推荐使用 class_getInstanceVariable(我已经在使用)和 key-value-coding(根本不起作用)。

这一定是以前做过的。谁能帮帮我?

编辑:到目前为止,我已经尝试过:

@interface MKMapSnapshotter() {
    @public VKMapSnapshotCreator *_lodpiSnapshotCreator;
    @public VKMapSnapshotCreator *_hidpiSnapshotCreator;
}

@end

编译成功,但是在尝试使用它时,Swift 一直坚持认为成员 _lodpiSnapshotCreator 和 _hidpiSnapshotCreator 不存在。

【问题讨论】:

  • 我不知道您要对这些变量做什么,但为 MKMapSnapshotter 类编写扩展可能会更容易
  • 转到 MKMapSnaphotter 并为要访问的变量创建 getter 和 setter 方法。
  • @AgentSmith 尝试访问我的 getter 方法会导致 [MKMapSnapshotter _hidpiSnapshotCreator]: unrecognized selector sent to instance。
  • 我想扩展也行不通,我打算写一个测试分机来查看所有内容,但我找不到提到这些lodpiSnapshotCreatorhidpiSnapshotCreator...无论如何,在 iOS 中看到 dpi 有点奇怪,我通常只在 Android 项目中看到这些
  • @JacobBoyd 这是针对 macOS 的。我可能应该在问题中说,哎呀

标签: objective-c swift macos instance-variables access-modifiers


【解决方案1】:

由于我们没有或控制源代码,我们无法将变量更改为属性。刚刚尝试过这适用于您的情况:

extension MKMapSnapshotter {
   func getPrivateVariable() -> String? {
       return value(forKey: "_lodpiSnapshotCreator") as? String
   }

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

您可以找到有关此here 的更多信息。

如果这不起作用,那么我相信没有办法从 Swift 访问 Objective-C 实例变量。只有 Objective-C 属性被映射到 Swift 属性。

希望这会有所帮助!

【讨论】:

  • getPrivateVariable() 只为我返回 nil。
  • @PeterW。忘了提到覆盖 value(forUndefinedKey:) 是可选的。如果私有变量在类中不存在 value(forKey:) 将崩溃,除非您覆盖 value(forUndefinedKey:) 并提供默认值。
  • 我真的只需要那个属性,所以很遗憾这对我不起作用。不管怎样,谢谢!
  • 你能把VKMapSnapshotCreator *转换成String吗?
猜你喜欢
  • 1970-01-01
  • 2013-04-22
  • 1970-01-01
  • 1970-01-01
  • 2015-11-14
  • 2016-02-23
  • 2015-03-20
  • 2017-03-11
  • 1970-01-01
相关资源
最近更新 更多