Skip to content

Instantly share code, notes, and snippets.

@enigmaticape
Created November 19, 2012 20:13
Show Gist options
  • Save enigmaticape/4113587 to your computer and use it in GitHub Desktop.
Save enigmaticape/4113587 to your computer and use it in GitHub Desktop.
A short digression on Objective C runtime type encoding
#import <Foundation/Foundation.h>
#import "SomeObject.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
/* lets encode some types and see what they look like */
NSLog(@"char : %s", @encode( typeof( char ) ) );
NSLog(@"char * : %s", @encode( typeof( char *) ) );
NSLog(@"int : %s", @encode( typeof( int ) ) );
NSLog(@"float : %s", @encode( typeof( float ) ) );
NSLog(@"float * : %s", @encode( typeof( float*) ) );
NSLog(@"void : %s", @encode( typeof( void ) ) );
NSLog(@"void * : %s", @encode( typeof( void *) ) );
NSLog(@"NSString * : %s", @encode( typeof( NSString *) ) );
NSLog(@"NSObject * : %s", @encode( typeof( NSObject *) ) );
/*
NSNumber is an NSValue subtype, so it encodes
type information, which we can retrieve
*/
NSNumber * aFloat = [NSNumber numberWithFloat:123.456];
NSLog(@"aFloat : %s", [aFloat objCType]);
NSUInteger size;
NSGetSizeAndAlignment( [aFloat objCType],
&size,
NULL );
NSLog(@"Size of value in aFloat (in bytes) : %li", size);
/*
or we can do that the other way around, and provide
the type info ourselves
*/
int val = 42;
NSValue * aValue = [NSValue valueWithBytes: &val
objCType: @encode(typeof(int))
];
/*
later, we can check it to see what we have,
and if the type is right, we can get the value
back out. NSNumber obviously does this for us
for numeric types.
*/
int outval = 0;
if( 0 == strcmp( [aValue objCType], @encode( typeof(int) ) ) ) {
[aValue getValue:&outval];
NSLog(@"aValue had an integer value of %i", outval);
}
/*
Now let's see how that works out on class methods
*/
SEL selector
= @selector(someMethodWithAchar:anInt:aFloat:aString:);
SomeObject * obj = [[SomeObject alloc]init];
NSMethodSignature * sig = [obj methodSignatureForSelector:selector];
NSUInteger arg_count = [sig numberOfArguments];
for( NSUInteger i = 0; i < arg_count; i++ ) {
const char * type = [sig getArgumentTypeAtIndex:i];
NSGetSizeAndAlignment( type,
&size,
NULL );
NSLog( @"Arg Type : %s, Size : %li",
type,
size
);
}
}
return 0;
}
[10523:403] char : c
[10523:403] char * : *
[10523:403] int : i
[10523:403] float : f
[10523:403] float * : ^f
[10523:403] void : v
[10523:403] void * : ^v
[10523:403] NSString * : @
[10523:403] NSObject * : @
[10523:403] aFloat : f
[10523:403] Size of value in aFloat (in bytes) : 4
[10523:403] aValue had an integer value of 42
[10523:403] Arg Type : @, Size : 8
[10523:403] Arg Type : :, Size : 8
[10523:403] Arg Type : c, Size : 1
[10523:403] Arg Type : i, Size : 4
[10523:403] Arg Type : f, Size : 4
[10523:403] Arg Type : @, Size : 8
#import <Foundation/Foundation.h>
@interface SomeObject : NSObject
- (NSObject*) someMethodWithAchar:(char) aChar
anInt:(int) anInt
aFloat:(float) aFloat
aString:(NSString*) aString;
@end
#import "SomeObject.h"
@implementation SomeObject
- (NSObject*) someMethodWithAchar:(char) aChar
anInt:(int) anInt
aFloat:(float) aFloat
aString:(NSString*) aString
{
return nil;
}
@end
@enigmaticape
Copy link
Author

From 'A short digression on Objective C runtime type encoding' on Enigmatic Ape blog at http://www.enigmaticape.com/blog/a-short-digression-on-objective-c-runtime-type-encoding/

Part of a series about supercharging performSelector by wrapping NSInvocation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment