读YYModel 心得体会

心得一.使用 objc_msgSend 强制转换类型(以下两种方式):
    1.NSString *(*fn)(id, SEL, NSString *) = (NSString *(*)(id, SEL, NSString *))objc_msgSend;

      fn(self, @selector(method1:), @"呵呵");

    2.((uint16_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter);

    3.调用 IMP 方法

    IMP result7 = class_getMethodImplementation([ViewController class], @selector(method0:));

    int (*px)(id, SEL, NSString *) = (int (*)(id, SEL, NSString *))result7;

  // - 下边的两种写法都可以

    1. px(nil, nil, @"ssss");      2. px(self, @selector(method0:), @"ssss");

心得二: 使用一个枚举值 代表多个变量
// - 这个 type 一共 64位 第一个后八位标示数据的类型(id, char*, bool, BOOL, int, short 等)  第二个后八位标示** 第三个后八位标示属性的属性(copy, retain, nonatomic, weak, assign)
typedef NS_OPTIONS(NSUInteger, YYEncodingType) {

    YYEncodingTypeMask       = 0xFF, ///< mask of type value

    YYEncodingTypeUnknown    = 0, ///< unknown
    YYEncodingTypeVoid       = 1, ///< void
    YYEncodingTypeBool       = 2, ///< bool
    YYEncodingTypeInt8       = 3, ///< char / BOOL
    YYEncodingTypeUInt8      = 4, ///< unsigned char
    YYEncodingTypeInt16      = 5, ///< short
    YYEncodingTypeUInt16     = 6, ///< unsigned short
    YYEncodingTypeInt32      = 7, ///< int
    YYEncodingTypeUInt32     = 8, ///< unsigned int
    YYEncodingTypeInt64      = 9, ///< long long
    YYEncodingTypeUInt64     = 10, ///< unsigned long long
    YYEncodingTypeFloat      = 11, ///< float
    YYEncodingTypeDouble     = 12, ///< double
    YYEncodingTypeLongDouble = 13, ///< long double
    YYEncodingTypeObject     = 14, ///< id
    YYEncodingTypeClass      = 15, ///< Class
    YYEncodingTypeSEL        = 16, ///< SEL
    YYEncodingTypeBlock      = 17, ///< block
    YYEncodingTypePointer    = 18, ///< void*
    YYEncodingTypeStruct     = 19, ///< struct
    YYEncodingTypeUnion      = 20, ///< union
    YYEncodingTypeCString    = 21, ///< char*
    YYEncodingTypeCArray     = 22, ///< char[10] (for example)
    
    YYEncodingTypeQualifierMask   = 0xFF00,   ///< mask of qualifier
    YYEncodingTypeQualifierConst  = 1 << 8,  ///< const
    YYEncodingTypeQualifierIn     = 1 << 9,  ///< in
    YYEncodingTypeQualifierInout  = 1 << 10, ///< inout
    YYEncodingTypeQualifierOut    = 1 << 11, ///< out
    YYEncodingTypeQualifierBycopy = 1 << 12, ///< bycopy
    YYEncodingTypeQualifierByref  = 1 << 13, ///< byref
    YYEncodingTypeQualifierOneway = 1 << 14, ///< oneway
    
    YYEncodingTypePropertyMask         = 0xFF0000, ///< mask of property
    YYEncodingTypePropertyReadonly     = 1 << 16, ///< readonly
    YYEncodingTypePropertyCopy         = 1 << 17, ///< copy
    YYEncodingTypePropertyRetain       = 1 << 18, ///< retain
    YYEncodingTypePropertyNonatomic    = 1 << 19, ///< nonatomic
    YYEncodingTypePropertyWeak         = 1 << 20, ///< weak
    YYEncodingTypePropertyCustomGetter = 1 << 21, ///< getter=
    YYEncodingTypePropertyCustomSetter = 1 << 22, ///< setter=
    YYEncodingTypePropertyDynamic      = 1 << 23, ///< @dynamic

};
@property (nonatomic, assign, readonly) YYEncodingType type;      ///< property's type

第一个后八位的的值的判断

switch (type & YYEncodingTypeMask) {
        case YYEncodingTypeBool:
        case YYEncodingTypeInt8:
        case YYEncodingTypeUInt8:
        case YYEncodingTypeInt16:
        case YYEncodingTypeUInt16:
        case YYEncodingTypeInt32:
        case YYEncodingTypeUInt32:
        case YYEncodingTypeInt64:
        case YYEncodingTypeUInt64:
        case YYEncodingTypeFloat:
        case YYEncodingTypeDouble:
        case YYEncodingTypeLongDouble: return YES;
        default: return NO;
    }

第三个后八位的值的判断

switch ((type & YYEncodingTypePropertyMask) | type) {

case YYEncodingTypePropertyReadonly:   
case YYEncodingTypePropertyReadonly:   
case YYEncodingTypePropertyRetain:   
case YYEncodingTypePropertyNonatomic:   
case YYEncodingTypePropertyWeak:   
case YYEncodingTypePropertyCustomGetter:   
case YYEncodingTypePropertyCustomSetter:   
case YYEncodingTypePropertyDynamic:  
case YYEncodingTypeLongDouble:
    }
心得三.字符串扫描器:
// - type = @"@\"NSString\"";
@property (nonatomic, copy, readonly) NSString *name; 

// - type = @"@\"<UIKeyInput><UIPickerViewDelegate><UITextSelecting>\"";
@property (nonatomic, strong) id <UIKeyInput, UIPickerViewDelegate, UITextSelecting> testAnyProp;

// - type = @"@\"NSString<UITabBarDelegate><UINavigationBarDelegate>\"";
@property (nonatomic, strong) NSString <UITabBarDelegate, UINavigationBarDelegate> *testAny1Prop;


  if ((type & YYEncodingTypeMask) == YYEncodingTypeObject && _typeEncoding.length) {
      NSScanner *scanner = [NSScanner scannerWithString:_typeEncoding];
      if (![scanner scanString:@"@\"" intoString:NULL]) continue;
      
      NSString *clsName = nil;
      if ([scanner scanUpToCharactersFromSet: [NSCharacterSet characterSetWithCharactersInString:@"\"<"] intoString:&clsName]) {
          if (clsName.length) _cls = objc_getClass(clsName.UTF8String);
      }
      
      NSMutableArray *protocols = nil;
      while ([scanner scanString:@"<" intoString:NULL]) {
          NSString* protocol = nil;
          if ([scanner scanUpToString:@">" intoString: &protocol]) {
              if (protocol.length) {
                  if (!protocols) protocols = [NSMutableArray new];
                  [protocols addObject:protocol];
              }
          }
          [scanner scanString:@">" intoString:NULL];
      }
      _protocols = protocols;
  }
心得四: 信号量的使用
static dispatch_semaphore_t lock;
    dispatch_once(&onceToken, ^{
        lock = dispatch_semaphore_create(1);
    });
    dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
     // - do someting ...
    dispatch_semaphore_signal(lock);
心得五: C语言创建字典和让字典执行方法
 
 
// - c 语言让数组的每个对象执行某个方法  
// - OC 数据类型和 void* 互转 
  Person *person = [[Person alloc]init];
  void *vp = (__bridge void*)person;
  __unsafe_unretained Person *person = (__bridge Person *)vp;
// - c语言创建字典
static CFMutableDictionaryRef metaCache;
classCache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

// - 定义一个结构体
typedef struct {
    void *modelMeta;  ///< _YYModelMeta
    void *model;      ///< id (self)
    void *dictionary; ///< NSDictionary (json)
} ModelSetContext;

// - 结构体赋值
ModelSetContext context = {0};
context.modelMeta = (__bridge void *)(modelMeta);
context.model = (__bridge void *)(self);
context.dictionary = (__bridge void *)(dic)

// - arg1 : 数组, arg2 : 执行方法的元素的起始和结束为止, arg3 : 执行的方法, arg4 : 方法携带的第二个参数
CFArrayApplyFunction((CFArrayRef)modelMeta->_keyPathPropertyMetas,
                                 CFRangeMake(0, CFArrayGetCount((CFArrayRef)modelMeta->_keyPathPropertyMetas)),
                                 ModelSetWithPropertyMetaArrayFunction,
                                 &context);

// - 让数组的每个元素执行的方法 arg1 : 数组的每个元素, arg2 : 另一个参数 即上文的 context
static void ModelSetWithPropertyMetaArrayFunction(const void *_propertyMeta, void *_context) {
    ModelSetContext *context = _context;
    __unsafe_unretained NSDictionary *dictionary = (__bridge NSDictionary *)(context->dictionary);
    __unsafe_unretained _YYModelPropertyMeta *propertyMeta = (__bridge _YYModelPropertyMeta *)(_propertyMeta);
    if (!propertyMeta->_setter) return;
    id value = nil;
    
    if (propertyMeta->_mappedToKeyArray) {
        value = YYValueForMultiKeys(dictionary, propertyMeta->_mappedToKeyArray);
    } else if (propertyMeta->_mappedToKeyPath) {
        value = YYValueForKeyPath(dictionary, propertyMeta->_mappedToKeyPath);
    } else {
        value = [dictionary objectForKey:propertyMeta->_mappedToKey];
    }
    
    if (value) {
        __unsafe_unretained id model = (__bridge id)(context->model);
        ModelSetValueForProperty(model, value, propertyMeta);
    }
}

// - 让字典的每个键值对执行某个方法
// - arg1 : 字典, arg2 : 执行的方法, arg3 : 方法携带的第二个参数
CFDictionaryApplyFunction((CFDictionaryRef)dic, ModelSetWithDictionaryFunction, &context);

// - 让字典的每个键值对执行的方法 arg1 : 键名, arg2 : 键值, arg3 : 另一个参数 即上文的 context
static void ModelSetWithDictionaryFunction(const void *_key, const void *_value, void *_context) {
    ModelSetContext *context = _context;
    __unsafe_unretained _YYModelMeta *meta = (__bridge _YYModelMeta *)(context->modelMeta);
    __unsafe_unretained _YYModelPropertyMeta *propertyMeta = [meta->_mapper objectForKey:(__bridge id)(_key)];
    __unsafe_unretained id model = (__bridge id)(context->model);
    while (propertyMeta) {
        if (propertyMeta->_setter) {
            ModelSetValueForProperty(model, (__bridge __unsafe_unretained id)_value, propertyMeta);
        }
        propertyMeta = propertyMeta->_next;
    };
}

猜你喜欢

转载自blog.csdn.net/qq_27074387/article/details/79726918