如何在 Obj-C 或 Swift 中访问私有实例变量?
Posted
技术标签:
【中文标题】如何在 Obj-C 或 Swift 中访问私有实例变量?【英文标题】:How do I access private instance variables in Obj-C or Swift? 【发布时间】:2018-08-01 04:58:02 【问题描述】:我正在尝试在 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。
我想扩展也行不通,我打算写一个测试分机来查看所有内容,但我找不到提到这些lodpiSnapshotCreator
或 hidpiSnapshotCreator
...无论如何,在 ios 中看到 dpi 有点奇怪,我通常只在 android 项目中看到这些
@JacobBoyd 这是针对 macOS 的。我可能应该在问题中说,哎呀
【参考方案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
吗?以上是关于如何在 Obj-C 或 Swift 中访问私有实例变量?的主要内容,如果未能解决你的问题,请参考以下文章
如何在同一框架内访问 Objective-C 中的内部 Swift 类?
可互操作的 Obj-C typedef NS_ENUM 到 swift