Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/98.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 将新类添加到运行时时是否可能收到通知?(目标C)_Ios_Objective C_Objective C Runtime - Fatal编程技术网

Ios 将新类添加到运行时时是否可能收到通知?(目标C)

Ios 将新类添加到运行时时是否可能收到通知?(目标C),ios,objective-c,objective-c-runtime,Ios,Objective C,Objective C Runtime,Objective-C运行时允许分别使用objc\u allocateClassPair和objc\u registerClassPair动态创建和注册类对。将新类添加到运行时时是否可能收到通知?(我只关心注册的Objective-C类,如果这有帮助的话,未注册的类将是一种奖励。) 如果无法得到通知,下一个最有效的方法是什么?大多数iOS设备都有严重的计算限制,因此我的选择是有限的。我愿意接受一些运行时黑客的攻击,如果这能使它成为可能的话。我意识到我可以只钩住+加载,但这只适用于NSObject

Objective-C运行时允许分别使用
objc\u allocateClassPair
objc\u registerClassPair
动态创建和注册类对。将新类添加到运行时时是否可能收到通知?(我只关心注册的Objective-C类,如果这有帮助的话,未注册的类将是一种奖励。)

如果无法得到通知,下一个最有效的方法是什么?大多数iOS设备都有严重的计算限制,因此我的选择是有限的。我愿意接受一些运行时黑客的攻击,如果这能使它成为可能的话。我意识到我可以只钩住
+加载
,但这只适用于NSObject子类,而不是纯Swift类

“纯敏捷类?但纯敏捷类不是客观的C类!”你说?再想想。尝试使用运行时内省一个纯Swift类,您将看到它有着比看上去更多的东西!“如何能够动态添加一个Swift类?”好吧,我可以加载一个使用Swift的动态框架

既然@SpaceDog提出了这个问题,这就是我正在开发的一个开发工具。进一步澄清:我自己不知道何时调用
objc\u allocateClassPair
objc\u registerClassPair
,因为我的项目是一个库

简短回答:没有。 长回答:有点。 有两种方法可以做到这一点。遗憾的是,这两种方法都需要一个看门狗线程和轮询

不需要重写符号,就无法使用同步回调。
(当然,如果这是一种选择,那么您有一整套其他解决方案)

  • 第一个选项,只使用公共API:您可以随时观察
    objc\u getClassList
    的计数变化

    此解决方案的问题是,它将强制将所有可能只是加载到共享DYLD缓存中的类加载到用户空间中。这种情况只发生一次,但这样做会对性能造成相当大的影响。当然不适合冷启动时间

    注意:
    objc_getClassList
    的排序顺序没有很好的定义(在内部它依赖于一个不稳定的哈希表),因此没有很好的方法(例如小于
    O(N)
    storage/time)来确定具体添加了哪个类


  • 第二种选择,可能是更可行的选择,是(ab)使用特定于调试器的API
    gdb_objc_实现的类

    这是一个类名(
    const char*
    )到类指针(aka.
    objc_class
    )的
    NXMapTable
    (objective-c运行时中使用的超旧哈希表实现)

    注意:
    NXMapTable
    不再位于公共标题中,因为OSX版本非常旧(10.4?),因此您需要从中获取最新版本的
    maptable.h

    用法示例:

    #import "maptable.h"
    
    extern NXMapTable *gdb_objc_realized_classes;
    
    int main() {
        printf("Realized classes: %d\n", NXCountMapTable(gdb_objc_realized_classes));
    
        Class superClass = [NSObject class];
        Class myKls = objc_allocateClassPair(superClass, "TestClass", 0);
        objc_registerClassPair(myKls);
    
        printf("Realized classes: %d\n", NXCountMapTable(gdb_objc_realized_classes));
    }
    
    另请注意:
    gdb_objc_实现的_类
    具有线程安全保证,因此如果有多个线程可能注册类,则可能会遇到问题


  • 这些解决方案允许您知道何时添加类,但不一定知道添加的特定类

    最后,如果你担心内存(因为你可能应该考虑基础框架中只有1500个类),一个选项可能是保持一个类似于已知注册类的数据结构,然后,当<代码> ObjcGueCuthListList的结果发生变化时,找出哪个类没有通过bloom过滤器,您就拥有了最新注册的类

    但是,作为一种概率数据结构,您可能会有误报-例如,如果指针/名称哈希不够好,某些类可能会漏掉


    祝你好运。

    你这是什么意思?在哪种情况下,类将被添加到运行时?举个例子。@SpaceDog:可以使用
    objc\u allocateClassPair
    动态分配类,然后通过
    objc\u registerClassPair
    注册类。原因很简单:我想监视我正在使用的开发人员实用程序的已注册类列表。