- 给分类动态的添加属性
@interface NSObject (TGTest)
@property (nonatomic, strong) NSString* test;
//这样写会报错
@end
#import "NSObject+ TGTest.h"
#import <objc/runtime.h>
@implementation NSObject (TGTest)
- (void)setTest:(NSString*)test{
//将属性同对象关联
objc_setAssociatedObject(self,@selector(setTest), test, OBJC_ASSOCIATION_COPY_NONATOMIC);}
- (NSString*)test{
//对出 key 关联的对象属性 return objc_getAssociatedObject(self, _cmd);}
@end
_cmd在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例
static char kExtendVarKey; // 键名
- (void)someCategoryMethod
{
NSString *extendVar = objc_getAssociatedObject(self, &kExtendVarKey);
if(!extendVar){
extendVar = @"someText";
objc_setAssociatedObject(self, &kExtendVarKey, extendVar, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
}
** 使用_cmd可以直接使用该@selector的名称,即someCategoryMethod,并且能保证改名称不重复 **
- (void)someCategoryMethod
{
NSString *extendVar = objc_getAssociatedObject(self, _cmd);
if(!extendVar){
extendVar = @"someText";
objc_setAssociatedObject(self, _cmd, extendVar, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
}
- 字典转模型
KVC做法
+ (instancetype)itemWithDict:(NSDictionary *)dict
{
// KVC做法: 遍历字典里面的所有key去模型中找,找到就赋值,找不到就会报错,模型作为key,不能为空
TGItem *item = [[self alloc] init];
[item setValuesForKeysWithDictionary:dict];
return item;
}
- (void)setValue:(id)value forKey:(NSString *)key
{
if ([key isEqualToString:@"id"]) {
[self setValue:value forKeyPath:@"ID"];
}else{
[super setValue:value forKey:key];
}
}
运行时
+ (instancetype)itemWithDict:(NSDictionary *)dict
{
XMGHtmlItem *item = [XMGHtmlItem objcWithDict:dict mapDict:@{@"ID":@"id"}];
// 遍历模型中属性名去字典中查找,如果找到就赋值,
return item;
}
+ (instancetype)objcWithDict:(NSDictionary *)dict mapDict:(NSDictionary *)mapDict
{
id objc = [[self alloc] init];
// 遍历模型中属性
unsigned int count = 0;
Ivar *ivars = class_copyIvarList(self, &count);
for (int i = 0 ; i < count; i++) {
Ivar ivar = ivars[i];
// 属性名称
NSString *ivarName = @(ivar_getName(ivar));
ivarName = [ivarName substringFromIndex:1];
id value = dict[ivarName];
// 需要由外界通知内部,模型中属性名对应字典里面的哪个key
// ID -> id
if (value == nil) {
if (mapDict) {
NSString *keyName = mapDict[ivarName];
value = dict[keyName];
}
}
[objc setValue:value forKeyPath:ivarName];
}
return objc;
}
- 方法的交换
@implementation UIImage (Extension)
/**
* 只要分类被装载到内存中,就会调用1次
*/
+ (void)load
{
Method otherMehtod = class_getClassMethod(self, @selector(imageWithName:));
Method originMehtod = class_getClassMethod(self, @selector(imageNamed:));
// 交换2个方法的实现
method_exchangeImplementations(otherMehtod, originMehtod);
}
+ (UIImage *)imageWithName:(NSString *)name
{
BOOL iOS7 = [[UIDevice currentDevice].systemVersion floatValue] >= 7.0;
UIImage *image = nil;
if (iOS7) {
NSString *newName = [name stringByAppendingString:@"_os7"];
image = [UIImage imageWithName:newName];
}
if (image == nil) {
image = [UIImage imageWithName:name];
}
return image;
}
@end