函数'dlopen()'是私有API吗?

23

我想在iOS平台上使用'dlopen()'函数调用动态库,'dlopen()'函数是私有API吗?


嘿,@Donald,你能否接受我的答案,以便未来的观察者可以看到吗? - NSProgrammer
没有。这在文档中已经提到了。https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW3 - Mike Glukhov
1个回答

25
我多年来一直在iOS上成功使用dlopen。在我的使用情况中,我使用dlopen按需加载公共系统框架,而不是在应用程序启动时加载它们。效果非常好!
[编辑] - 自iOS 8起,扩展和共享框架禁止使用dlopen,但应用程序本身仍然可以使用dlopen(现在还记录为不仅支持Apple框架,还支持自定义框架)。请参阅此Apple文档中的“将包含应用部署到旧版本的iOS”部分。
[编辑] - 编造的示例
#import <dlfcn.h>

void printApplicationState()
{
    Class UIApplicationClass = NSClassFromString(@"UIApplication");
    if (Nil == UIApplicationClass) {
        void *handle = dlopen("System/Library/Frameworks/UIKit.framework/UIKit", RTLD_NOW);
        if (handle) {
            UIApplicationClass = NSClassFromString(@"UIApplication");
            assert(UIApplicationClass != Nil);
            NSInteger applicationState = [UIApplicationClass applicationState];
            printf("app state: %ti\n", applicationState);
            if (0 != dlclose(handle)) {
                printf("dlclose failed! %s\n", dlerror());
            }
        } else {
            printf("dlopen failed! %s\n", dlerror());
        }
    } else {
        printf("app state: %ti\n", [UIApplicationClass applicationState]);
    }
}

你在应用商店遭到拒绝的问题上没有遇到过任何困难吗? - David Liu
1
@DavidLiu - 没有问题。您无法链接任何未签名的二进制文件,但是使用dlopen与操作系统提供的公共框架或动态库没有问题。这可能已经改变了,但我在两家公司工作过并且做到了这一点:其中一家公司拥有大约150万MAU,另一家公司拥有1.5亿MAU。 - NSProgrammer
你能帮我提供一个例子吗?如何使用dlopen加载动态框架? - Baljeet Singh
void* handle = dlopen("/System/Library/Frameworks/UIKit.framework/UIKit", RTLD_NOW); 然后您可以通过调用 dlclose(handle); 卸载它(将加载计数减少1)。请务必阅读文档以获取更多信息。https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/dlopen.3.html - NSProgrammer
@NSProgrammer 你是如何使用 @imports/#imports 的呢?这似乎是一个不错的方法,可以避免加载数百个共享 dylibs,但我不确定你如何编译和使用 UIKit 等库...有什么想法吗? - iOSAddicted
@iOSAddicted 导入不是问题,链接器才是问题所在。调用 dylib 的符号将强制在链接时解析链接,而使用 dyld 加载则不会出现这种情况。解决方案是使用间接引用 - 例如 NSClassFromString 和 NSSelectorFromString。对于枚举,你没问题,但对于外部常量,你需要将值复制到二进制文件的 var/const 局部变量中。这很麻烦,但可行。 - NSProgrammer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接