Reputation: 645
My objective is to collect the OS Version, release details of MAC 10.10.
I have found a way to collect the version details in MAC 10.10 and as well as from prev. version from the link
How do I determine the OS version at runtime in OS X or iOS (without using Gestalt)?
While I compile it is throwing error at "objc_msgSend_stret", when i search the /usr/include/objc folder itself was not exist in my MAC. i could see only gcc present and all my code was build with it.
Is there any best way to copy the output of
[[NSProcessInfo processInfo], @selector(operatingSystemVersion)] to a struct as "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
}
Upvotes: 2
Views: 2314
Reputation: 6570
I'm guessing that you aren't building this with the 10.10 SDK, otherwise you could simply remove your call to objc_msgSend_stret
and call operatingSystemVersion
directly.
// 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
}
If you're using an earlier SDK, then NSOperatingSystemVersion
and -[NSProcessInfo operatingSystemVersion]
are both undefined. Since you can't use -[NSProcessInfo operatingSystemVersion]
without getting a compiler error, the safer way to call it and get the return value of a non-object type is with NSInvocation
. This is still technically risky because you're assigning the return value to a different type of struct (MyOperatingSystemVersion
vs. NSOperatingSystemVersion
), but you have defined them both the same so it should be ok. I tested this with Xcode 5 / 10.9 SDK and it worked fine.
// 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
}
That should take care of the problem, but the safest thing to do is build with the 10.10 SDK and use the first example.
Upvotes: 2