我正在研究一个内部工具(永远不会提交给App Store的东西),我想在运行时检测一个类是Objective-C还是Swift.这可能吗?
如果出于学术目的,你绝对必须知道一个类是否是用swift代码创建的(而不是以一种容易被愚弄的方式objc_allocateClassPair
),那么你可以利用可以找到的信息objc-runtime-new.h
,特别是标志与...有关FAST_IS_SWIFT
.
要提取这些标志而不必使您的源代码C++或包含大量私有标题,您可以使用类似于以下内容,但请注意:这是超级易碎的.
这可能不是ABI强制执行的任何地方,任何未来的版本都可以改变这一点而不会产生任何后果.请记住等等.
没有进一步的麻烦,疯狂的黑客随之而来:
#define FAST_IS_SWIFT (1UL<<0) #define FAST_HAS_DEFAULT_RR (1UL<<1) #define FAST_DATA_MASK 0xfffffffcUL uintptr_t getClassBits(Class kls) { #if __LP64__ typedef uint32_t mask_t; #else typedef uint16_t mask_t; #endif return ((const struct { /* struct objc_class */ Class isa; Class superclass; /* struct cache_t */ void *bucket_t; mask_t mask; mask_t occupied; /* struct class_data_bits_t */ uintptr_t bits; } *) (__bridge const void *) kls)->bits; }
这是在objc-runtime-new.h
没有所有额外的C++开销的情况下重新创建结构格式.
一旦你得到了一个类的位,只需将它与它FAST_IS_SWIFT
(例如bits & FAST_IS_SWIFT
)进行比较,你应该得到你的答案.