在 YYModel 中 使用 类对象包装 C 语言指针方便访问
YYClassIvarInfo 包装 Ivar
YYClassMethodInfo 包装 Method
YYClassPropertyInfo 包装 objc_property_t
YYClassInfo 包装
NSDictionary<NSString *, YYClassIvarInfo *> *ivarInfos;
NSDictionary<NSString *, YYClassMethodInfo *> *methodInfos;
NSDictionary<NSString *, YYClassPropertyInfo *> *propertyInfos;
YYEncodingType 来表示 数据的类型, 修饰词 通过三个掩码来表示不同的含义
typedef NS_OPTIONS(NSUInteger, YYEncodingType) {
YYEncodingTypeMask = 0xFF, ///< mask of type value
YYEncodingTypeUnknown = 0, ///< unknown
...
YYEncodingTypeCArray = 22, ///< char[10] (for example)
YYEncodingTypeQualifierMask = 0xFF00, ///< mask of qualifier
YYEncodingTypeQualifierConst = 1 << 8, ///< const
...
YYEncodingTypeQualifierOneway = 1 << 14, ///< oneway
YYEncodingTypePropertyMask = 0xFF0000, ///< mask of property
YYEncodingTypePropertyReadonly = 1 << 16, ///< readonly
...
YYEncodingTypePropertyDynamic = 1 << 23, ///< @dynamic
};
YYModel中归档和解档的操作 写下宏定义, 就会自动替换下边的方法
#ifndef YYdArchiverAndUnarchiver
#define YYdArchiverAndUnarchiver \
- (void)encodeWithCoder:(NSCoder *)aCoder { [self modelEncodeWithCoder:aCoder]; } \
- (id)initWithCoder:(NSCoder *)aDecoder { return [self modelInitWithCoder:aDecoder]; } \
- (id)copyWithZone:(NSZone *)zone { return [self modelCopy]; } \
- (NSUInteger)hash { return [self modelHash]; } \
- (BOOL)isEqual:(id)object { return [self modelIsEqual:object]; }
#endif
内联函数的宏定义
#define force_inline __inline__ __attribute__((always_inline))
YYModel 中, one调用modelSetWithDictionary:方法, 在遍历 one 对象的属性时候, 如果 one 对象有一个 (meta->_nsType == YYEncodingTypeNSUnknown) && (meta->_type & YYEncodingTypeMask == YYEncodingTypeObject)类型的对象one1, 则认为这个one1有自定义的对象类型, 则对这个对象调用 modelSetWithDictionary: 这样可以递归下去.
method_getTypeEncoding 的解析
// - 已知方法 testInstanceMethod:andValue 现解析 method_getTypeEncoding
- (int)testInstanceMethod:(NSString *)name andValue:(NSNumber *)value {
NSLog(@"%@", name);
return value.intValue;
}
typeEncode = i32@0:8@16@24 解析
" i " : 返回值的编码为 i(int 类型)
" 32 " : 所有的参数加一起,占用 32 个字节
" @ " : 第一个参数的编码为 @ (id 类型 ,即 self)
" 0 " : 编码为@的参数起始字节 因为是第一个参数, 所以是 0;
" : " : 第二个参数的编码为 : (sel , 即 @selector:(testInstanceMethod:andValue))
" 8 " : 编码为: 的参数起始字节 因为是前一个是id(8字节) 所以这里起始是 8
" @ " : 第三个参数的编码为 @ (id 类型 ,即 name)
" 16 " : 编码为@的参数起始字节 前两个参数是 id(8字节) 和 sel (8字节), 所以这里起始是 16
" @ " : 第四个参数的编码为 @ (id 类型 ,即 value)
" 16 " : 编码为@的参数起始字节 前三个参数是 id(8字节) 和 sel (8字节)和 id(8字节) , 所以这里起始是 24