【问题标题】:Accessing <objc/runtime.h> from Cycript从 Cycript 访问 <objc/runtime.h>
【发布时间】:2015-09-28 13:31:52
【问题描述】:

我不希望能够使用关联对象和 ISA swizzle,但我不知道如何导入 objc/runtime.h 以与 Cycript 一起使用。我在控制台和 .js 文件中都试过了,但没有运气。

理想情况下,我也想弄清楚如何包含框架。

【问题讨论】:

  • 关联对象不需要 objc/runtime.h。就ISA swizzling 而言,这是在没有经验的人手中非常危险的事情之一。控制台和 Javascript 与此有什么关系?
  • 问题是关于 Cycript

标签: ios cycript


【解决方案1】:

似乎 runtime.h 的一个子集默认包含在 Cycript 环境中。例如,class_copyMethodList 和 objc_getClass 无需任何额外工作即可工作。

var count = new new Type(@encode(int));
var methods = class_copyMethodList(objc_getClass("NSObject"), count);

然而 objc_setAssociatedObject 没有被引用:

objc_getAssociatedObject(someVar, "asdf")
#ReferenceError: Can't find variable: objc_getAssociatedObject

经过大量搜索,我意识到答案就在我的眼皮底下。 limneos 的 weak_classdump 使用运行时进行转储,而 Cycript 的 tutorial 展示了如何抓取 C 函数。

我最终得到的解决方案是这样的:

function setAssociatedObject(someObject, someValue, constVoidPointer) {
    SetAssociatedObject = @encode(void(id, const void*, id, unsigned long))(dlsym(RTLD_DEFAULT, "objc_setAssociatedObject"))
    SetAssociatedObject(someObject, constVoidPointer, someValue, 1)
}

function getAssociatedObject(someObject, constVoidPointer) {
    GetAssociatedObject = @encode(id(id, const void*))(dlsym(RTLD_DEFAULT, "objc_getAssociatedObject"))
    return GetAssociatedObject(someObject, constVoidPointer)
}

它是这样使用的:

# create void pointer (probably should be a global variable for later retrieval)
voidPtr = new new Type(@encode(const void))

someVar = [[NSObject alloc] init]
setAssociatedObject(someVar, @[@"hello", @"world"], voidPtr)
getAssociatedObject(someVar, voidPtr)
# spits out @["Hello", "World"]

【讨论】:

    猜你喜欢
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多