hri*_*.to 5 objective-c ios ios7 ios8
使用[NSMethodSignature getArgumentTypeAtIndex]函数时,我遇到了很奇怪的行为.根据objective-c 类型编码,它返回BOOL类型的'@'字符.如果我使用objc\runtime.h库方法method_getTypeEncoding BOOL类型被正确表示为'B',但是我不明白为什么它不能使用更高级别的层NSMethodSignature.以下代码演示了此问题:
-(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
}
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是(至少对男性而言)打印出以下内容:
来自NSMethodSignature的BOOL arg:@
来自objc/runtime.h的BOOL arg:B
我目前正在使用我自己的实现来避免这种奇怪的行为,但我想知道我是否遗漏了某些东西或者它只是一个bug.我唯一的线索是BOOL是原始的,就像这样,在调用objective-c方法时不能直接使用它.但是,当我尝试检查它[object isKingOfClass:[NSNumber class]]时返回NO.
UPDATE
好的我已将XCode更新到最新版本(6.1 6A1052d),情况大大改善.但是我现在的问题是将unsigned char编码与real bool编码区分开来.我知道在旧版本BOOL是typedef作为char,但我怎么能完成真正的char vs BOOL编码?我现在的结果是:
对于模拟器iPhone6和真实设备iPhone6,我收到:
argument 2: -------- -------- -------- --------
type encoding (B) 'B'
flags {}
BOOL arg from NSMethodSignature: B
BOOL arg from objc/runtime.h: B
Run Code Online (Sandbox Code Playgroud)
这是真棒,但对于模拟器iPhone4s,我得到的真实设备iPhone5:
argument 2: -------- -------- -------- --------
type encoding (c) 'c'
flags {isSigned}
BOOL arg from NSMethodSignature: c
BOOL arg from objc/runtime.h: c
Run Code Online (Sandbox Code Playgroud)
我很确定如果我检查iPhone5s它将获得与iPhone6相同的输出(因为我认为这都是关于64位架构).所以我现在的问题是如何正确地解决旧设备,如何区分BOOL的char?或者我应该假设如果编码是'c'并且参数等于'1'我们有YES,而对于'0'我们有NO?
char *buf1 = @encode(BOOL);
NSLog(@"bool type is: %s", buf1);
Run Code Online (Sandbox Code Playgroud)
在32位模拟器上,encode(BOOL)返回'c',而在64位时,它返回'B'.在Build Settings中,将Architectures更改为$(ARCHS_STANDARD_32_BIT),然后它将为您返回'c'.
在objc/objc.h文件中.
#define OBJC_BOOL_DEFINED
/// Type to represent a boolean value.
#if !defined(OBJC_HIDE_64) && TARGET_OS_IPHONE && __LP64__
typedef bool BOOL;
#else
typedef signed char BOOL;
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C"
// even if -funsigned-char is used.
#endif
Run Code Online (Sandbox Code Playgroud)
32位中的BOOL是一种签名字符.您可以将它与unsigned char区分开来.
@encode(char) --> 'c'
@encode(unsigned char) --> 'C'
Run Code Online (Sandbox Code Playgroud)
你可以从这里告诉设备是32位还是64位,如果是32位,'c'对BOOL检查有效.
| 归档时间: |
|
| 查看次数: |
646 次 |
| 最近记录: |