Как получить строку версии ОС в MAC 10.10 без использования гештальта

Моя цель - собрать версию ОС, детали релиза MAC 10.10.

Я нашел способ собрать информацию о версии в MAC 10.10, а также из пред. версия по ссылке

Как определить версию ОС во время выполнения в OS X или iOS (без использования 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 ответ

Решение

Я предполагаю, что вы не создаете это с 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, Это все еще технически рискованно, потому что вы присваиваете возвращаемое значение другому типу структуры (MyOperatingSystemVersion против 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 и использовать первый пример.

Другие вопросы по тегам