YYModel 源码心得(一)

在 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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值