@encode編譯器指令和Objective-C類型編碼介紹

0x01 encode編譯器指令

@encode是編譯器指令之一。

@encode返回一個給定的Objective-C 類型編碼(Objective-C Type Encodings)。

這是一種內部表示的字符串,類似於 ANSI C 的 typeof 操作。

蘋果的 Objective-C 運行時庫(runtime)內部利用類型編碼幫助加快消息分發。

 

0x02 Objective-C類型編碼

 

0x03 Objective-C方法編碼

 

0x04 打印類型編碼舉例

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        NSLog(@"int        : %s", @encode(int));
        NSLog(@"float      : %s", @encode(float));
        NSLog(@"float *    : %s", @encode(float*));
        NSLog(@"char       : %s", @encode(char));
        NSLog(@"char *     : %s", @encode(char *));
        NSLog(@"BOOL       : %s", @encode(BOOL));
        NSLog(@"void       : %s", @encode(void));
        NSLog(@"void *     : %s", @encode(void *));
        
        NSLog(@"NSObject * : %s", @encode(NSObject *));
        NSLog(@"NSObject   : %s", @encode(NSObject));
        NSLog(@"[NSObject] : %s", @encode(typeof([NSObject class])));
        NSLog(@"NSError ** : %s", @encode(typeof(NSError **)));
        
        int intArray[5] = {1, 2, 3, 4, 5};
        NSLog(@"int[]      : %s", @encode(typeof(intArray)));
        
        float floatArray[3] = {0.1f, 0.2f, 0.3f};
        NSLog(@"float[]    : %s", @encode(typeof(floatArray)));
        
        typedef struct _struct {
            short a;
            long long b;
            unsigned long long c;
        } Struct;
        NSLog(@"struct     : %s", @encode(typeof(Struct)));
        
        return 0;
    }
}

/*
Output:
2018-07-27 03:34:54.610 test[3084:97707] int        : i
2018-07-27 03:34:54.611 test[3084:97707] float      : f
2018-07-27 03:34:54.611 test[3084:97707] float *    : ^f
2018-07-27 03:34:54.611 test[3084:97707] char       : c
2018-07-27 03:34:54.611 test[3084:97707] char *     : *
2018-07-27 03:34:54.611 test[3084:97707] BOOL       : c
2018-07-27 03:34:54.612 test[3084:97707] void       : v
2018-07-27 03:34:54.612 test[3084:97707] void *     : ^v
2018-07-27 03:34:54.612 test[3084:97707] NSObject * : @
2018-07-27 03:34:54.612 test[3084:97707] NSObject   : {NSObject=#}
2018-07-27 03:34:54.612 test[3084:97707] [NSObject] : #
2018-07-27 03:34:54.612 test[3084:97707] NSError ** : ^@
2018-07-27 03:34:54.612 test[3084:97707] int[]      : [5i]
2018-07-27 03:34:54.612 test[3084:97707] float[]    : [3f]
2018-07-27 03:34:54.612 test[3084:97707] struct     : {_struct=sqQ}
Program ended with exit code: 0
*/

 

0x05 類型代碼的實用方法

遍歷NSArray或NSDictionary的時候,我們可能需要判斷當前位置的數據類型,再決定對應的操作方法:

NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:
                    [NSNumber numberWithBool:YES],@"key1",
                    [NSNumber numberWithDouble:1.00f],@"key2",
                    [NSNumber numberWithInt:1],@"key3",
                    [NSNumber numberWithFloat:33.0f], @"key4", 
                    nil];  

    //快速枚舉,僅適用於Objective-C 2.0
    for(NSString *key in dic){  
        id value = [dic valueForKey:key];  
        if([value isKindOfClass:[NSNumber class]]){  
            const char * pObjCType = [((NSNumber*)value) objCType];  
            if (strcmp(pObjCType, @encode(int))  == 0) {  
                NSLog(@"字典中key=%@的值是int類型,值爲%d",key,[value intValue]);  
            }  
            if (strcmp(pObjCType, @encode(float)) == 0) {  
                NSLog(@"字典中key=%@的值是float類型,值爲%f",key,[value floatValue]);  
            }  
            if (strcmp(pObjCType, @encode(double))  == 0) {  
                NSLog(@"字典中key=%@的值是double類型,值爲%f",key,[value doubleValue]);  
            }  
            if (strcmp(pObjCType, @encode(BOOL)) == 0) {  
                NSLog(@"字典中key=%@的值是bool類型,值爲%i",key,[value boolValue]);  
            }  
        }  
    }  

 

發佈了67 篇原創文章 · 獲贊 28 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章