【问题标题】:How to check Mac OS X version at runtime如何在运行时检查 Mac OS X 版本
【发布时间】:2020-10-30 18:13:54
【问题描述】:

我正在使用以下代码在运行时检查 OS X 版本。

if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_10)
{
    /* On a 10.10.x or earlier system */
}

但是这个条件在 10.10.4 OS X 上返回 false。我使用的是 Xcode 6.3.2。

根据AppKit Release Notes for OS X v10.11,它应该可以工作。

if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9) {
  /* On a 10.9.x or earlier system */
} else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_10) {
  /* On a 10.10 - 10.10.x system */
} else {
  /* 10.11 or later system */
}

【问题讨论】:

  • 如果你打开NSApplication.h,你看到NSAppKitVersionNumber10_10在那里定义了吗?
  • 是的。我附上了截图。
  • false 是正确的:在 10.10.4 floor(NSAppKitVersionNumber) = 1348 等于或小于 NSAppKitVersionNumber10_10 = 1343
  • @vadian 根据 OS X v10.11 的 AppKit 发行说明,它应该可以工作。

标签: objective-c macos cocoa nsapplication osx-elcapitan


【解决方案1】:

从 Xcode 9.0 开始,您可以使用以下代码。 参考Apple documentation

斯威夫特

if #available(macOS 10.13, *) {
      // macOS 10.13 or later code path
} else {
      // code for earlier than 10.13
}

Objective-C

if (@available(macOS 10.13, *)) {
      // macOS 10.13 or later code path
} else {
      // code for earlier than 10.13
}

【讨论】:

  • 调用 @available(macOS 10.14, ) 会导致在 NSTextView 子类中无限调用“布局”方法。您需要改为 @available(,macOS 10.14)
【解决方案2】:

所以你看到的10_10 的#define 是10.10.0

如果您查找旧版本号,您会看到特定的#define 用于 MacOS 10.7.4、MacOS 10.5.3。

这里发生的情况是,在 10.10.4 机器上(如你我的机器),10.10.4 的应用套件编号大于为 10.10.0 定义。

也就是说,我很快做到了:

func applicationDidFinishLaunching(aNotification: NSNotification) {
    print("appkit version number is \(NSAppKitVersionNumber)")
}

我得到了:

appkit version number is 1348.17

所以您的代码实际上是在检查 10.10.0 及更早版本。

如果您想检查所有版本的 Yosemite 及更新版本,您可能需要执行类似的操作

#ifdef NSAppKitVersionNumber10_11
if (floor(NSAppKitVersionNumber) < NSAppKitVersionNumber10_11)
{
    /* On a 10.10.x or earlier system */
}    
#endif

一旦您开始使用 Xcode 7 构建(并且一旦 Apple 开始为 El Capitan 版本定义官方发布版本/内部版本号),它将编译

FWIW,我拥有的 Xcode 7 beta 在 10.11 SDK 中包含“NSAppKitVersionNumber10_10_3”。

【讨论】:

  • Xcode 7 beta 没有 NSAppKitVersionNumber10_11。我已经添加了我的解决方法。
【解决方案3】:

如果需要支持多系统(可以适配方法返回值):

#import <objc/message.h>

+ (NSString *)systemVersion
{
  static NSString *systemVersion = nil;

  if (!systemVersion) {
    typedef struct {
      NSInteger majorVersion;
      NSInteger minorVersion;
      NSInteger patchVersion;
    } MyOperatingSystemVersion;

    if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) {
      MyOperatingSystemVersion version = ((MyOperatingSystemVersion(*)(id, SEL))objc_msgSend_stret)([NSProcessInfo processInfo], @selector(operatingSystemVersion));
      systemVersion = [NSString stringWithFormat:@"Mac OS X %ld.%ld.%ld", (long)version.majorVersion, version.minorVersion, version.patchVersion];
    }
    else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
      SInt32 versMaj, versMin, versBugFix;
      Gestalt(gestaltSystemVersionMajor, &versMaj);
      Gestalt(gestaltSystemVersionMinor, &versMin);
      Gestalt(gestaltSystemVersionBugFix, &versBugFix);
      systemVersion = [NSString stringWithFormat:@"Mac OS X %d.%d.%d", versMaj, versMin, versBugFix];
#pragma clang diagnostic pop
    }
  }

  return systemVersion;
}

【讨论】:

    【解决方案4】:

    从 Yosemite 开始,你可以使用[NSProcessInfo processInfo].operatingSystemVersion 并在结构体NSOperatingSystemVersion 中测试结果。

    【讨论】:

    • 谢谢,但我支持 10.6 及更高版本。
    • 如果 respondsToSelector 例如做operatingSystemVersion 如果不使用格式塔
    【解决方案5】:

    更新:

    使用#define NSAppKitVersionNumber10_10_Max 1349

    旧:

    从 10.11 SDK 开始

    #define NSAppKitVersionNumber10_7_2 1138.23
    #define NSAppKitVersionNumber10_7_3 1138.32
    #define NSAppKitVersionNumber10_7_4 1138.47
    #define NSAppKitVersionNumber10_8 1187
    #define NSAppKitVersionNumber10_9 1265
    #define NSAppKitVersionNumber10_10 1343
    #define NSAppKitVersionNumber10_10_2 1344
    #define NSAppKitVersionNumber10_10_3 1347
    

    对于 10.10.4 它的 1348.0(来自 NSLog 输出)

    他们增加了 10.10.x 常量的小数部分。

    解决方法是在 10.11 上使用 CFBundleVersion/System/Library/Frameworks/AppKit.framework/Resources/Info.plist

    if (NSAppKitVersionNumber < 1391.12)
    {
        /* On a 10.10.x or earlier system */
    }
    

    注意:我的 OS X 10.11 构建版本是 15A244a。如果有人第一次构建,请更新 if 条件中的值。

    【讨论】:

      猜你喜欢
      • 2012-09-09
      • 2011-12-16
      • 2011-02-07
      • 2014-02-28
      • 2016-08-14
      • 1970-01-01
      • 1970-01-01
      • 2019-08-05
      相关资源
      最近更新 更多