基于 iOS 版本的不显眼的运行前定义值

Posted

技术标签:

【中文标题】基于 iOS 版本的不显眼的运行前定义值【英文标题】:Unobtrusive pre-runtime defined values based on iOS version 【发布时间】:2013-06-11 20:25:10 【问题描述】:

有什么方法可以根据 ios 版本为我的应用程序设置未缓存和几乎(如果不是完全)预先确定的值,而无需在运行时手动调用初始化代码?

我不是在寻找需要我在应用程序运行时不断检查操作系统或必须在运行时通过 AppDelegate 进行调用来初始化许多全局变量的解决方案。

【问题讨论】:

编译时不存在关于什么系统正在运行代码的信息。怎么可能?你见过Run time vs compile time iPhone version check吗? @JoshCaswell 很抱歉造成混乱。我没想到实际的编译时间检查,但有一些替代方案。我只是不想在需要枚举值时不断检查 iOS 版本。 您的问题似乎是在询问预处理器宏的时间——您多次提到它们。如果您正在寻找他们的替代方法,您应该更清楚地说明这一点。 当然,我明白这一点,但你现在的问题有点像“我的医生说我的饮食中需要更多的钾,但我讨厌香蕉,那么我应该吃哪种香蕉?”当您实际上正在寻找香蕉以外的选择时。 我认为这也是一个有效的问题;我只是想解释一下,根据您的 cmets,您似乎在寻找的内容与问题不符。也许我解释得不够好...... 【参考方案1】:

您无法在编译时检查系统版本。这些信息根本不存在。

由于您希望避免在应用程序运行期间多次重新检查,因此您能做的最好的事情就是在进程生命周期的早期检查并存储该信息。这可能是您的应用程序委托的适当任务。当您收到application:didFinishLaunchingWithOptions: 时,请执行通常的运行时检查并将结果提供给任何其他需要它的控制器。或者让每个关心的控制器在创建时进行检查。

您还可以使用constructor 属性创建一个函数,该函数将在非常 提前运行——事实上,在main() 之前,尽管after framework classes have been loaded。这可以简单地用系统版本初始化一个全局变量,然后你可以在任何你喜欢的地方访问。

【讨论】:

您的意思是在方法声明之前的行中添加:__attribute__((constructor))?这是否会导致函数在应用程序加载任何内容之前运行,这样我就不必检查值是否已初始化,而只需相信它已被初始化,因为它已在任何调用之前运行做到了吗? 该属性不适用于方法;它必须是一个函数。是的,正如我所说,该函数将在main() 之前运行,因此在UIApplicationMain() 之前运行,并且在您的任何其他代码之前运行。甚至可能为时过早;我不能 100% 确定 UIDevice 是否会被初始化。你必须尝试一下。 啊!对。使用方法是没有意义的,因为我不需要任何东西的实例。那么这对我来说肯定会很好。我将编辑我的问题,以反映我从这一切中得到了什么。 @JoshCaswell 正如我在iOS app in pure C 中所证明的,您可以在__attribute__((constructor)) 函数中使用objc 类。 @Daij-Djan 它将工作(我使用构造函数创建了一个 UIView 子类),并且我已经证明它在模拟器和设备上都是可靠的:***.com/questions/10289890/…。跨度> 【参考方案2】:

使用@JoshCaswell 的建议,我尝试了以下方式:

static BOOL iOS6OrGreater;

__attribute__((constructor))
static void iOS6OrGreaterInitialization()iOS6OrGreater = [[[UIDevice currentDevice] systemVersion] compare:@"6.0" options:NSNumericSearch] != NSOrderedDescending;

static int MY_DEFINED_ENUM_NAME()return (iOS6OrGreater) ? IOS6_OR_GREATER_ENUM : IOS5_OR_LESSER_ENUM;

但是我收到了'UITextAlignmentCenter' is deprecated: first deprecated in iOS 6.0 警告。

【讨论】:

只是禁止警告:***.com/questions/1902021/… @RichardJ.RossIII 谢谢!我也收到了Value Conversion Issue,但我不知道警告标志名称是什么。我怎么会想办法抑制它,因为我不想抑制所有警告。 你不要抑制它,你应该将值转换为int @RichardJ.RossIII 我是,但是当我获取值时,我忘了说明它是一个带括号的函数。这是一个愚蠢的错误。

以上是关于基于 iOS 版本的不显眼的运行前定义值的主要内容,如果未能解决你的问题,请参考以下文章

ASP .Net MVC 3:自定义不显眼的验证

如何在 ASP NET MVC 中自定义不显眼的验证 JQuery 消息?

Android 基于Gradle 7.2+,自定义插件示例(实测7.4.2也可以运行)

如何在 ASP.NET MVC 3 中自定义不显眼的验证以匹配我的风格?

转一个简单的例子,学习自定义注解和AOP

在 Android 中不会阻止拖放的不显眼的弹出窗口