YYModel 源码解读(二)之YYClassInfo.h (1)
生活随笔
收集整理的這篇文章主要介紹了
YYModel 源码解读(二)之YYClassInfo.h (1)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1 NS_ASSUME_NONNULL_BEGIN
2 NS_ASSUME_NONNULL_END
為了兼容Swift 中的 ? 和 ! oc 在6.3引入了兩個新的類型注釋:__nullable和__nonnull , 在字面上很好理解 可能為空, 不為空,
在上面代碼中間則表示 默認的所有的屬性都不能為空,這樣我們在敲碼的過程中只需要手寫__nullable的類型就可以了?
1 /** 2 Type encoding's type. 3 */ 4 typedef NS_OPTIONS(NSUInteger, YYEncodingType) { 5 YYEncodingTypeMask = 0xFF, ///< mask of type value 6 YYEncodingTypeUnknown = 0, ///< unknown 7 YYEncodingTypeVoid = 1, ///< void 8 YYEncodingTypeBool = 2, ///< bool 9 YYEncodingTypeInt8 = 3, ///< char / BOOL 10 YYEncodingTypeUInt8 = 4, ///< unsigned char 11 YYEncodingTypeInt16 = 5, ///< short 12 YYEncodingTypeUInt16 = 6, ///< unsigned short 13 YYEncodingTypeInt32 = 7, ///< int 14 YYEncodingTypeUInt32 = 8, ///< unsigned int 15 YYEncodingTypeInt64 = 9, ///< long long 16 YYEncodingTypeUInt64 = 10, ///< unsigned long long 17 YYEncodingTypeFloat = 11, ///< float 18 YYEncodingTypeDouble = 12, ///< double 19 YYEncodingTypeLongDouble = 13, ///< long double 20 YYEncodingTypeObject = 14, ///< id 21 YYEncodingTypeClass = 15, ///< Class 22 YYEncodingTypeSEL = 16, ///< SEL 23 YYEncodingTypeBlock = 17, ///< block 24 YYEncodingTypePointer = 18, ///< void* 25 YYEncodingTypeStruct = 19, ///< struct 26 YYEncodingTypeUnion = 20, ///< union 27 YYEncodingTypeCString = 21, ///< char* 28 YYEncodingTypeCArray = 22, ///< char[10] (for example) 29 30 YYEncodingTypeQualifierMask = 0xFF00, ///< mask of qualifier 31 YYEncodingTypeQualifierConst = 1 << 8, ///< const 32 YYEncodingTypeQualifierIn = 1 << 9, ///< in 33 YYEncodingTypeQualifierInout = 1 << 10, ///< inout 34 YYEncodingTypeQualifierOut = 1 << 11, ///< out 35 YYEncodingTypeQualifierBycopy = 1 << 12, ///< bycopy 36 YYEncodingTypeQualifierByref = 1 << 13, ///< byref 37 YYEncodingTypeQualifierOneway = 1 << 14, ///< oneway 38 39 YYEncodingTypePropertyMask = 0xFF0000, ///< mask of property 40 YYEncodingTypePropertyReadonly = 1 << 16, ///< readonly 41 YYEncodingTypePropertyCopy = 1 << 17, ///< copy 42 YYEncodingTypePropertyRetain = 1 << 18, ///< retain 43 YYEncodingTypePropertyNonatomic = 1 << 19, ///< nonatomic 44 YYEncodingTypePropertyWeak = 1 << 20, ///< weak 45 YYEncodingTypePropertyCustomGetter = 1 << 21, ///< getter= 46 YYEncodingTypePropertyCustomSetter = 1 << 22, ///< setter= 47 YYEncodingTypePropertyDynamic = 1 << 23, ///< @dynamic 48 };上邊的代碼 就涉及到了運行時中的類型解碼方面的知識了,在此總結一下
關于Type Encodings 的官方解釋?, @encode 是一個編譯器指令,返回個內部表示的字符串 , 比如:?@encode(int)→?i ,作用就是可以加快運行時庫的消息分發,
需要注意的是:
- 指針的標準編碼是加一個前置的?^,而?char *?擁有自己的編碼?*。這在概念上是很好理解的,因為 C 的字符串被認為是一個實體,而不是指針。
- BOOL?是?c,而不是某些人以為的?i。原因是?char?比?int?小,且在 80 年代 Objective-C 最開始設計的時候,每一個 bit 位都比今天的要值錢(就像美元一樣)。BOOL?更確切地說是?signed char?(即使設置了?-funsigned-char?參數),以在不同編譯器之間保持一致,因為?char?可以是?signed?或者?unsigned。
- 直接傳入?NSObject?將產生?#。但是傳入?[NSObject class]?產生一個名為?NSObject?只有一個類字段的結構體。很明顯,那就是?isa?字段,所有的?NSObject?實例都用它來表示自己的類型。
通過打印的數據,看起來更加直觀
1 NSLog(@"int : %s", @encode(int)); 2 NSLog(@"float : %s", @encode(float)); 3 NSLog(@"float * : %s", @encode(float*)); 4 NSLog(@"char : %s", @encode(char)); 5 NSLog(@"char * : %s", @encode(char *)); 6 NSLog(@"BOOL : %s", @encode(BOOL)); 7 NSLog(@"void : %s", @encode(void)); 8 NSLog(@"void * : %s", @encode(void *)); 9 10 NSLog(@"NSObject * : %s", @encode(NSObject *)); 11 NSLog(@"NSObject : %s", @encode(NSObject)); 12 NSLog(@"[NSObject] : %s", @encode(typeof([NSObject class]))); 13 NSLog(@"NSError ** : %s", @encode(typeof(NSError **))); 14 15 int intArray[5] = {1, 2, 3, 4, 5}; 16 NSLog(@"int[] : %s", @encode(typeof(intArray))); 17 18 float floatArray[3] = {0.1f, 0.2f, 0.3f}; 19 NSLog(@"float[] : %s", @encode(typeof(floatArray))); 20 21 typedef struct _struct { 22 short a; 23 long long b; 24 unsigned long long c; 25 } Struct; 26 NSLog(@"struct : %s", @encode(typeof(Struct))); 1 2016-05-23 10:42:00.172 ModelBenchmark[1661:72558] int : i 2 2016-05-23 10:42:00.173 ModelBenchmark[1661:72558] float : f 3 2016-05-23 10:42:00.173 ModelBenchmark[1661:72558] float * : ^f 4 2016-05-23 10:42:00.173 ModelBenchmark[1661:72558] char : c 5 2016-05-23 10:42:00.173 ModelBenchmark[1661:72558] char * : * 6 2016-05-23 10:42:00.173 ModelBenchmark[1661:72558] BOOL : B 7 2016-05-23 10:42:00.174 ModelBenchmark[1661:72558] void : v 8 2016-05-23 10:42:00.174 ModelBenchmark[1661:72558] void * : ^v 9 2016-05-23 10:42:00.174 ModelBenchmark[1661:72558] NSObject * : @ 10 2016-05-23 10:42:00.174 ModelBenchmark[1661:72558] NSObject : {NSObject=#} 11 2016-05-23 10:42:00.174 ModelBenchmark[1661:72558] [NSObject] : # 12 2016-05-23 10:42:00.174 ModelBenchmark[1661:72558] NSError ** : ^@ 13 2016-05-23 10:42:00.174 ModelBenchmark[1661:72558] int[] : [5i] 14 2016-05-23 10:42:00.174 ModelBenchmark[1661:72558] float[] : [3f] 15 2016-05-23 10:42:00.174 ModelBenchmark[1661:72558] struct : {_struct=sqQ}關于 Type Property 和 Functions 的官方解釋?,可以參考官方文檔獲取編譯后的內容
?
1 YYEncodingType YYEncodingGetType(const char *typeEncoding);定義一個方法 把typeEncoding 轉為自定義的枚舉類型,方便管理和使用,
?
1 YYEncodingType YYEncodingGetType(const char *typeEncoding) { 2 3 // 判斷外部傳入值 是不是nil,如果為空 ,返回 YYEncodingTypeUnknown 4 // 轉換const 限定符 5 char *type = (char *)typeEncoding; 6 if (!type) return YYEncodingTypeUnknown; 7 size_t len = strlen(type); 8 if (len == 0) return YYEncodingTypeUnknown; 9 10 // 找出修飾語 11 YYEncodingType qualifier = 0; 12 bool prefix = true; 13 14 // 可能多個修飾符 15 while (prefix) { 16 17 switch (*type) { 18 case 'r': { 19 qualifier |= YYEncodingTypeQualifierConst; 20 type++; 21 } break; 22 case 'n': { 23 qualifier |= YYEncodingTypeQualifierIn; 24 type++; 25 } break; 26 case 'N': { 27 qualifier |= YYEncodingTypeQualifierInout; 28 type++; 29 } break; 30 case 'o': { 31 qualifier |= YYEncodingTypeQualifierOut; 32 type++; 33 } break; 34 case 'O': { 35 qualifier |= YYEncodingTypeQualifierBycopy; 36 type++; 37 } break; 38 case 'R': { 39 qualifier |= YYEncodingTypeQualifierByref; 40 type++; 41 } break; 42 case 'V': { 43 qualifier |= YYEncodingTypeQualifierOneway; 44 type++; 45 } break; 46 default: { prefix = false; } break; 47 } 48 } 49 50 // 是否還存在后續的字符 51 len = strlen(type); 52 if (len == 0) return YYEncodingTypeUnknown | qualifier; 53 54 // 查找數據類型 55 switch (*type) { 56 case 'v': return YYEncodingTypeVoid | qualifier; 57 case 'B': return YYEncodingTypeBool | qualifier; 58 case 'c': return YYEncodingTypeInt8 | qualifier; 59 case 'C': return YYEncodingTypeUInt8 | qualifier; 60 case 's': return YYEncodingTypeInt16 | qualifier; 61 case 'S': return YYEncodingTypeUInt16 | qualifier; 62 case 'i': return YYEncodingTypeInt32 | qualifier; 63 case 'I': return YYEncodingTypeUInt32 | qualifier; 64 case 'l': return YYEncodingTypeInt32 | qualifier; 65 case 'L': return YYEncodingTypeUInt32 | qualifier; 66 case 'q': return YYEncodingTypeInt64 | qualifier; 67 case 'Q': return YYEncodingTypeUInt64 | qualifier; 68 case 'f': return YYEncodingTypeFloat | qualifier; 69 case 'd': return YYEncodingTypeDouble | qualifier; 70 case 'D': return YYEncodingTypeLongDouble | qualifier; 71 case '#': return YYEncodingTypeClass | qualifier; 72 case ':': return YYEncodingTypeSEL | qualifier; 73 case '*': return YYEncodingTypeCString | qualifier; 74 case '^': return YYEncodingTypePointer | qualifier; 75 case '[': return YYEncodingTypeCArray | qualifier; 76 case '(': return YYEncodingTypeUnion | qualifier; 77 case '{': return YYEncodingTypeStruct | qualifier; 78 case '@': { 79 if (len == 2 && *(type + 1) == '?') 80 return YYEncodingTypeBlock | qualifier; 81 else 82 return YYEncodingTypeObject | qualifier; 83 } 84 default: return YYEncodingTypeUnknown | qualifier; 85 } 86 }上邊的方法 主要是找出所有的和屬性相關的信息,并轉換為自定義的類型
轉載于:https://www.cnblogs.com/machao/p/5519605.html
總結
以上是生活随笔為你收集整理的YYModel 源码解读(二)之YYClassInfo.h (1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C/C++中的拷贝构造函数和赋值构造函数
- 下一篇: 布拉科公司是一家为汽车工业生产零部件的小