I've encountered really odd behaviour when using [NSMethodSignature getArgumentTypeAtIndex] function. It returns me '@' character for BOOL type which in wrong according to objective-c type encodings. If I use objc\runtime.h library method method_getTypeEncoding BOOL type is correctly represented as a 'B', however I don't understand why it's not working with higher level layer NSMethodSignature. Following code demonstrates the problem:
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSInvocation* inv = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(viewDidAppear:)]];
const char* encFromGetArgument = [[inv methodSignature] getArgumentTypeAtIndex:2];
const char* encFromMethodSignature = method_getTypeEncoding(class_getInstanceMethod([self class], @selector(viewDidAppear:)));;
const char* methodEncodingPure = [[[[NSString stringWithUTF8String:encFromMethodSignature] componentsSeparatedByCharactersInSet:[NSCharacterSet decimalDigitCharacterSet]] componentsJoinedByString:@""] UTF8String];//remove stack sizes
NSLog(@"BOOL arg from NSMethodSignature: %s", encFromGetArgument);
NSLog(@"BOOL arg from objc/runtime.h: %c", methodEncodingPure[3]);//first type is for return, second is target, third is selector
}
The above surprisingly(at least for men) prints the following:
BOOL arg from NSMethodSignature: @
BOOL arg from objc/runtime.h: B
I'm currently using my own implementation to avoid this odd behaviour however I want to know if I'm missing something or it's just a bug. My only clue is that BOOL is primitive and like this it cannot be used directly when calling objective-c methods. However when I try to check it [object isKingOfClass:[NSNumber class]] returns NO.
UPDATE
Ok I've update XCode to the latest version(6.1 6A1052d) and situation greatly improves. However my problem now is to distinguish unsigned char encoding from real bool encoding. I know in old versions BOOL is typedef as a char, but how I can accomplish real char vs BOOL encoding? My results now are:
For Simulator iPhone6 and real device iPhone6 I received:
argument 2: -------- -------- -------- --------
type encoding (B) 'B'
flags {}
BOOL arg from NSMethodSignature: B
BOOL arg from objc/runtime.h: B
which is awesome, however for simulator iPhone4s, and real device iPhone5 I'm getting:
argument 2: -------- -------- -------- --------
type encoding (c) 'c'
flags {isSigned}
BOOL arg from NSMethodSignature: c
BOOL arg from objc/runtime.h: c
I'm pretty sure that if I check iPhone5s it'll get the same output as iPhone6(as I think it's all about the 64-bit architecture). So my question now is how to properly workaround older devices, how to distinguish char of BOOL for them? Or should I just assume that if encoding is 'c' and argument is equal to '1' we have YES, and for '0' we have NO?