可在编译时调整的 Objective-C 框架
Posted
技术标签:
【中文标题】可在编译时调整的 Objective-C 框架【英文标题】:Objective-C framework which can be adjusted in compiling time 【发布时间】:2018-10-09 14:03:16 【问题描述】:更详细的解释(小版本请查看TL;DR到底):
我创建了一个可以在 Github 上使用的框架。其中,有 7 个宏定义了框架的编译方式。我不能只用 static const
替换它们,因为其中 6 个宏用于在编译时从框架中删除一些东西。
这些宏可以分组:
第 1 组)在可用时使用框架
#define USE_THE_METAL_FRAMEWORK_WHEN_AVAILABLE true
#define USE_THE_OPENGL_FRAMEWORK_WHEN_AVAILABLE true
这些定义使框架使用 Metal 和 OpenGL 框架,即使它们没有被添加到项目中。这是使用dlopen
完成的。更多详情如下:
https://***.com/a/24266440/4370893
https://***.com/a/21375580/4370893
https://***.com/a/1354569/4370893
我使用它是为了让那些框架只有在它们可用时才能使用,因此开发人员可以为 macOS 10.6 构建他/她的应用程序,并且如果系统中可用的话,仍然可以使用 Metal。问题是:如果您的应用程序二进制文件在某处调用dlopen
,则无法将其添加到 Apple Store(即使您并没有真正使用使用它的功能),因此用户应该能够将其从如果他们愿意,可以编码。这删除了一些框架功能,但使其能够被提交。
第 2 组)我正在导入框架
#define IM_IMPORTING_THE_METAL_FRAMEWORK false
#define IM_IMPORTING_THE_OPENGL_FRAMEWORK false
这些定义使框架真正使用 Metal 和 OpenGL 框架,而不使用dlopen
。这样,它可以提交到 Apple Store 并仍然使用前面提到的功能。
第 3 组)行为改变
#define USER_NOTIFICATIONS_SHOULD_SHOW_A_BIGGER_ICON true
#define NSDEBUGLOG_SHOULD_PRINT_TO_A_DESKTOP_FILE_TOO true
第一个也可能导致Apple Store出现问题,第二个仅用于调试目的。
最后……
第 4 组)应在 Apple Store 发布
#define I_WANT_TO_BE_RELEASED_IN_APPLE_STORE false
那个是用来做那个的:
#if I_WANT_TO_BE_RELEASED_IN_APPLE_STORE == true
#define USER_NOTIFICATIONS_SHOULD_SHOW_A_BIGGER_ICON false
#define USE_THE_METAL_FRAMEWORK_WHEN_AVAILABLE false
#define USE_THE_OPENGL_FRAMEWORK_WHEN_AVAILABLE false
#endif
它会自动禁用可能导致 Apple Store 出现问题的三个定义。
不过,例如使用 Travis-CI 的人无法更改框架,除非他们将其完全复制到项目中。例如,为了解决这个问题(或至少减少它),这 7 个定义中的 5 个可以通过主项目中的文件进行更改。如果有人有其他可以解决问题的建议,我正在倾听。
(可选)如果这可以通过警告用户(通过 Xcode 或通过编译时错误)的方式完成,他/她需要设置那些很好的变量,因为这样可以避免问题与可能需要设置这些宏的用户一起使用。
TL;DR:是否可以在不修改框架本身的情况下更改框架内某些宏的值?
【问题讨论】:
【参考方案1】:没有。制作一些方法,用一些参数初始化你的模块。但无论如何你都无法使用 dlopen。
【讨论】:
我已经使用dlopen
... 没关系。问题只是能够在编译时使用宏将其删除。避免将其与参数一起使用不是一回事。 Apple 仍然会拒绝该应用程序,因为它存在于二进制文件中,并且他们不会停止分析您的应用程序逻辑以查看您是否正在使用它(即使他们没有您的应用程序的源代码)。
@vitormm,根本不要使用dlopen
。在编译时使用您的标志将其删除。对于其他选项,请使用动态参数。
那么只有在OpenGL和Metal这些框架可用的情况下,我该如何使用呢?
另外,为什么我不应该将dlopen
用于不会在 Apple Store 中分发的应用程序?
@vitormm 链接它们是可选的,而不是必需的。以上是关于可在编译时调整的 Objective-C 框架的主要内容,如果未能解决你的问题,请参考以下文章
iOS面试粮食Runtime—消息传递和转发机制Method Swizzling