Ios 将新类添加到运行时时是否可能收到通知?(目标C)
Objective-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
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)使用特定于调试器的APIgdb_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
注册类。原因很简单:我想监视我正在使用的开发人员实用程序的已注册类列表。