如何在不使用格式塔的情况下获取MAC 10.10中的操作系统版本字符串

时间:2014-08-21 15:18:57

标签: xcode macos operating-system osx-yosemite osx-yosemite-beta

我的目标是收集操作系统版本,发布MAC 10.10的详细信息。

我找到了一种方法来收集MAC 10.10以及prev中的版本细节。链接中的版本

How do I determine the OS version at runtime in OS X or iOS (without using Gestalt)?

虽然我编译它是在“objc_msgSend_stret”抛出错误,当我搜索/ usr / include / objc文件夹本身在我的MAC中不存在时。我只能看到gcc存在,我的所有代码都是用它构建的。

有没有最好的方法来复制

的输出

[[NSProcessInfo processInfo],@ selector(operatingSystemVersion)]到一个结构为“MyOperatingSystemVersion”?

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));
    // do whatever you want with the version struct here
}
else {
    UInt32 systemVersion = 0;
    OSStatus err = Gestalt(gestaltSystemVersion, (SInt32 *) &systemVersion);
    // do whatever you want with the systemVersion as before
}

1 个答案:

答案 0 :(得分:2)

我猜你没有使用10.10 SDK构建此功能,否则您只需移除对objc_msgSend_stret的通话并直接致电operatingSystemVersion即可。

// Built with 10.10 SDK
if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) {
    NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
    // do whatever you want with the version struct here
}
else {
    UInt32 systemVersion = 0;
    OSStatus err = Gestalt(gestaltSystemVersion, (SInt32 *) &systemVersion);
    // do whatever you want with the systemVersion as before
}

如果您使用的是较早的SDK,那么NSOperatingSystemVersion-[NSProcessInfo operatingSystemVersion]都是未定义的。由于您无法在不收到编译器错误的情况下使用-[NSProcessInfo operatingSystemVersion],因此调用它并获取非对象类型的返回值的更安全的方法是使用NSInvocation。这仍然存在技术风险,因为您将返回值分配给不同类型的结构(MyOperatingSystemVersionNSOperatingSystemVersion),但您已将它们定义为相同,因此应该没问题。我用Xcode 5 / 10.9 SDK进行了测试,结果很好。

// Built with 10.9 or earlier SDKs
if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) {
    MyOperatingSystemVersion version;
    NSMethodSignature *methodSignature = [[NSProcessInfo processInfo] methodSignatureForSelector:@selector(operatingSystemVersion)];
    NSInvocation *inv = [NSInvocation invocationWithMethodSignature:methodSignature];
    inv.selector = @selector(operatingSystemVersion);
    [inv invokeWithTarget:[NSProcessInfo processInfo]];
    [inv getReturnValue:&version];
    // do whatever you want with the version struct here
}
else {
    UInt32 systemVersion = 0;
    OSStatus err = Gestalt(gestaltSystemVersion, (SInt32 *) &systemVersion);
    // do whatever you want with the systemVersion as before
}

这应该解决问题,但最安全的做法是使用10.10 SDK构建并使用第一个示例。