按照这里的解释:
https://github.com/nst/iOS-Runtime-Headers
我正在尝试在TelephonyUtilities.framework包中获取TUPhoneLogger的类。但是,调试器始终显示“错误:未知类”。
我有两种不同的方法:
第一种方法:
NSBundle* b = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/TelephonyUtilities.framework"];
BOOL success = [b load];
NSLog(@"%@", [b definedClasses_dd]);
注意:我创建了一个@interface NSBundle(DDAdditions) 扩展:
- (NSArray *)definedClasses_dd {
NSMutableArray *array = [NSMutableArray array];
int numberOfClasses = objc_getClassList(NULL, 0);
Class *classes = calloc(sizeof(Class), numberOfClasses);
numberOfClasses = objc_getClassList(classes, numberOfClasses);
for (int i = 0; i < numberOfClasses; ++i) {
Class c = classes[i];
if ([NSBundle bundleForClass:c] == self) {
[array addObject:c];
const char* nameOfClass = class_getName(c);
NSString* classString = [NSString stringWithUTF8String:nameOfClass];
if([classString isEqualToString:@"TUPhoneLogger"]) {
NSLog(@"Found it! TUPhoneLogger");
id test= [[c alloc] init];
NSLog(@"test: %@", test);
}
}
}
free(classes);
第二种方法:
NSBundle* b = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/TelephonyUtilities.framework"];
Class telephonyClass = [b classNamed:@"TUPhoneLogger"];
id test= [[telephonyClass alloc] init];
NSLog(@"%@", test);
在调试器中:
答案 0 :(得分:6)
+1给Victor,因为我认为在项目中将Framework作为构建阶段库包含起来更简单。私有框架位于PrivateFrameworks
SDK子目录下,但除此之外,它的工作方式与公共框架类似(Victor的答案中描述了差异)。
我将提供另一种有效的技术,如果你想要动态加载:
#include <dlfcn.h>
#import <objc/runtime.h>
然后
void* handle = dlopen("/System/Library/PrivateFrameworks/TelephonyUtilities.framework/TelephonyUtilities", RTLD_NOW);
Class c = NSClassFromString(@"TUPhoneLogger");
id instance = [[c alloc] init];
dlclose(handle);
我认为dlopen()
的好处是你不必记得打电话给load
,这会让你进入第二个例子。缺点是你之后应该致电dlclose()
。
注意: dlopen()
与NSBundle bundleWithPath:
的路径略有差异(文件与目录)
注意++:此代码在模拟器中不起作用,因为模拟器可能缺少该框架(没有真正的手机功能)
在iOS 9.3中,Apple从SDK中删除了私有框架。因此,从那时起,如果Framework不是公共iOS框架之一,通常情况下你需要使用这种动态技术。 See this answer for more
答案 1 :(得分:2)
还有第三种方法(我更喜欢)
a)您静态链接到此框架(意味着,您将其添加到目标)
b)在.h类中定义必要的类(TUPhoneLogger)。您可以使用class-dump(-z)
来获取它c)你包含这个.h文件
d)您只需使用私有类,就像使用公共类一样。
小额外解释
私有框架和私有API没有“神奇”。唯一不同的是它们没有记录并包含在.h文件中。
步骤b)和c)用它们创建.h类,结果它们的使用方式与通常的公共API完全相同。