I came across really strange behavior when using the [NSMethodSignature getArgumentTypeAtIndex] function. It returns me the β@β character for the BOOL type, which is erroneous according to the objective-c encoding type . If I use the objc \ runtime.h library method, method_getTypeEncoding method The BOOL type is correctly represented as "B", however I do not understand why it does not work with the higher level NSMethodSignature. The 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];
The above unexpectedly (at least for men) prints the following:
BOOL arg of NSMethodSignature: @
BOOL arg of objc / runtime.h: B
I am currently using my own implementation to avoid this odd behavior, however I want to know if I am missing something or is it just a mistake. My only hint is that BOOL is primitive, and therefore it cannot be used directly when calling objective-c methods. However, when I try to check it, [object isKingOfClass: [NSNumber class]] returns NO.
UPDATE
Good. I updated Xcode to the latest version (6.1 6A1052d) and the situation has improved significantly. However, now my problem is to distinguish unsigned char encoding from real bool encoding. I know that in older versions of BOOL, typedef is like char, but how can I do real char vs BOOL encoding? Now my results:
For Simulator iPhone6 ββand real iPhone6 device 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 the iPhone4s simulator and the real iPhone5 device I get:
argument 2: -------- -------- -------- -------- type encoding (c) 'c' flags {isSigned} BOOL arg from NSMethodSignature: c BOOL arg from objc/runtime.h: c
I am almost sure that if I check iPhone5, it will get the same result as iPhone6 ββ(as I think, all about 64-bit architecture). So now my question is how to bypass old devices correctly, how to distinguish char from BOOL for them? Or should I just assume that if the encoding is "c" and the argument is "1", we have YES, but for "0" NO?