2

我的目标是收集 OS 版本,MAC 10.10 的发布细节。

我找到了一种方法来收集 MAC 10.10 以及上一个版本的详细信息。来自链接的版本

如何在 OS X 或 iOS(不使用格式塔)中确定运行时的操作系统版本?

当我编译它在“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
}
4

1 回答 1

2

我猜你不是用 10.10 SDK 构建的,否则你可以简单地删除你的调用objc_msgSend_stretoperatingSystemVersion直接调用。

// 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]编译器错误的情况下使用,调用它并获取非对象类型的返回值的更安全的方法是 with NSInvocation。这在技术上仍然存在风险,因为您将返回值分配给不同类型的结构(MyOperatingSystemVersionvs. NSOperatingSystemVersion),但是您已经将它们定义为相同的,所以应该没问题。我使用 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 构建并使用第一个示例。

于 2014-08-21T16:36:07.083 回答