为什么 CFBundleGetDataPointerForName 不适用于 iOS 8-style 框架?
Why doesn't CFBundleGetDataPointerForName work for iOS 8-style frameworks?
通常 iOS 您可以 load constants at runtime using CFBundleGetDataPointerForName
. However, I'm finding that CFBundleGetDataPointerForName
always returns NULL
pointers for constants defined in iOS-8 style frameworks, like the ones discussed in WWDC 2014 Session 416: Building Modern Frameworks。
为了复制,我只是用 Xcode 框架模板创建一个框架,添加一个构建脚本来制作一个通用二进制文件,然后将创建的框架拖到另一个有框架项目的项目中。然后我尝试像这样从中加载一个常量:
void * versionNumberConstant = CFBundleGetDataPointerForName(CFBundleGetMainBundle(), CFSTR("TestFramework2VersionNumber"));
NSLog(@"Version number was %@",versionNumberConstant ? @"PRESENT" : @"NULL"); // Prints NULL
出于复制目的,this repo has the framework project, and this repo 尝试使用 CFBundleGetDataPointerForName
从该框架加载常量。
我也可以用其他开发人员制作的框架复制这个问题,例如 AdMob's SDK。
以防指针不在 CFBundleGetMainBundle()
中出现问题,我还遍历了每个 CFBundleRef
并且无法从其中任何一个加载常量:
CFArrayRef array = CFBundleGetAllBundles();
for (int i = 0; i < CFArrayGetCount(array); i++) {
CFBundleRef bundleRef = (CFBundleRef)CFArrayGetValueAtIndex(array, i);
void * versionPointer = CFBundleGetDataPointerForName(bundleRef, CFSTR("TestFramework2VersionNumber"));
NSLog(@"Version pointer is %@",versionPointer ? @"PRESENT" : @"NULL");
}
有谁知道这是为什么,或者如果有一些构建设置我可以更改以修复它?
版本信息:
- Xcode: 版本 6.2 6C131e
- iOS: 8.2 (12D508)
- 设备:iPhone 6 / iPhone 6 模拟器
好的,问题是我需要加载该框架正在使用的特定包,如下所示:
NSURL *testFramework2URL = [[[[NSBundle mainBundle] resourceURL] URLByAppendingPathComponent:@"Frameworks" isDirectory:YES] URLByAppendingPathComponent:@"TestFramework2.framework"];
CFBundleRef bundleRef = CFBundleCreate(NULL, (__bridge CFURLRef)testFramework2URL);
NSLog(@"Bundle Ref = %@",bundleRef);
double * manualVersion = CFBundleGetDataPointerForName(bundleRef, CFSTR("TestFramework2VersionNumber"));
NSLog(@"Manual version = %@",manualVersion ? @"present" : @"NULL"); // Manual version = present
double version = *manualVersion;
NSLog(@"Version = %g",version); // Version = 1
我也可以使用 CFBundleGetAllBundles()
实现此目的,尽管我在问题中说了什么(我最初使用 CFBundleGetAllBundles()
函数或其他东西时一定是犯了错误。
通常 iOS 您可以 load constants at runtime using CFBundleGetDataPointerForName
. However, I'm finding that CFBundleGetDataPointerForName
always returns NULL
pointers for constants defined in iOS-8 style frameworks, like the ones discussed in WWDC 2014 Session 416: Building Modern Frameworks。
为了复制,我只是用 Xcode 框架模板创建一个框架,添加一个构建脚本来制作一个通用二进制文件,然后将创建的框架拖到另一个有框架项目的项目中。然后我尝试像这样从中加载一个常量:
void * versionNumberConstant = CFBundleGetDataPointerForName(CFBundleGetMainBundle(), CFSTR("TestFramework2VersionNumber"));
NSLog(@"Version number was %@",versionNumberConstant ? @"PRESENT" : @"NULL"); // Prints NULL
出于复制目的,this repo has the framework project, and this repo 尝试使用 CFBundleGetDataPointerForName
从该框架加载常量。
我也可以用其他开发人员制作的框架复制这个问题,例如 AdMob's SDK。
以防指针不在 CFBundleGetMainBundle()
中出现问题,我还遍历了每个 CFBundleRef
并且无法从其中任何一个加载常量:
CFArrayRef array = CFBundleGetAllBundles();
for (int i = 0; i < CFArrayGetCount(array); i++) {
CFBundleRef bundleRef = (CFBundleRef)CFArrayGetValueAtIndex(array, i);
void * versionPointer = CFBundleGetDataPointerForName(bundleRef, CFSTR("TestFramework2VersionNumber"));
NSLog(@"Version pointer is %@",versionPointer ? @"PRESENT" : @"NULL");
}
有谁知道这是为什么,或者如果有一些构建设置我可以更改以修复它?
版本信息:
- Xcode: 版本 6.2 6C131e
- iOS: 8.2 (12D508)
- 设备:iPhone 6 / iPhone 6 模拟器
好的,问题是我需要加载该框架正在使用的特定包,如下所示:
NSURL *testFramework2URL = [[[[NSBundle mainBundle] resourceURL] URLByAppendingPathComponent:@"Frameworks" isDirectory:YES] URLByAppendingPathComponent:@"TestFramework2.framework"];
CFBundleRef bundleRef = CFBundleCreate(NULL, (__bridge CFURLRef)testFramework2URL);
NSLog(@"Bundle Ref = %@",bundleRef);
double * manualVersion = CFBundleGetDataPointerForName(bundleRef, CFSTR("TestFramework2VersionNumber"));
NSLog(@"Manual version = %@",manualVersion ? @"present" : @"NULL"); // Manual version = present
double version = *manualVersion;
NSLog(@"Version = %g",version); // Version = 1
我也可以使用 CFBundleGetAllBundles()
实现此目的,尽管我在问题中说了什么(我最初使用 CFBundleGetAllBundles()
函数或其他东西时一定是犯了错误。