可在编译时调整的 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 框架的主要内容,如果未能解决你的问题,请参考以下文章

无法为本地pod框架桥接标头发出预编译头

iOS面试粮食Runtime—消息传递和转发机制Method Swizzling

iOS面试粮食Runtime—消息传递和转发机制Method Swizzling

刷新页面时调用RowDataBound事件

将Swift与Objective-C相结合

在 Objective-C(测试)代码中导入框架的 Swift 类