心得一.使用 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; }; }