一个模型类PCBitch
PCBitch.h
#import <Foundation/Foundation.h>
@interface PCBitch : NSObject
@property(nonatomic, copy, readonly) NSString *name;
- (void)sayHello;
@end
PCBitch.m
#import "PCBitch.h"
@interface PCBitch()
@property(nonatomic, assign) int age;
@property(nonatomic, assign) int height;
@property(nonatomic, copy) NSString *cupSize;
@end
@implementation PCBitch
- (instancetype)init {
if (self = [super init]) {
_name = @"Batrick";
_age = 21;
_height = 168;
_cupSize = @"C";
}
return self;
}
- (void)sayHello {
NSLog(@"Hello, I'm %@", _name);
}
- (void)sayHoney {
NSLog(@"Ai yo, honey~");
}
+ (void)papapa {
NSLog(@"papapapa");
}
@end
模型分类PCBitch+Asshole,动态添加“属性”
PCBitch+Asshole.h
#import "PCBitch.h"
@interface PCBitch (Asshole)
@property(nonatomic, copy) NSString *assholeName;
@end
PCBitch+Asshole.m
#import "PCBitch+Asshole.h"
#import <objc/runtime.h>
static char assholeNameChar;
@implementation PCBitch (Asshole)
- (void)setAssholeName:(NSString *)assholeName {
objc_setAssociatedObject(self, &assholeNameChar, assholeName, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)assholeName {
return objc_getAssociatedObject(self, &assholeNameChar);
}
@end
展示类PCBitchShowStage
#import "PCBitchShowStage.h"
#import "PCBitch.h"
#import "PCBitch+Asshole.h"
#import <objc/runtime.h>
@implementation PCBitchShowStage
void sayAhName(id self, SEL _cmd);
+ (void)show {
PCBitch *pBitch = [[PCBitch alloc] init];
[pBitch setValue:@"Zhangsan" forKey:@"_name"];
[pBitch sayHello];
// 添加属性
pBitch.assholeName = @"pppppp";
NSLog(@"The assholeName of the bitch: %@", pBitch.assholeName);
// // 利用runtime读取类属性
unsigned int propertyCount;
objc_property_t *propertyList = class_copyPropertyList([pBitch class], &propertyCount);
NSLog(@"property count: %zd", propertyCount);
for (int i=0; i<propertyCount; i++) {
objc_property_t property = propertyList[i];
NSString *propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
char returntype[512] = {};
method_getReturnType(class_getInstanceMethod([pBitch class], NSSelectorFromString(propertyName)), returntype, 512);
NSString *returnTypeStr = [NSString stringWithUTF8String:returntype];
// NSLog(@"property:%@, return type: %@", propertyName, returnTypeStr);
NSString *outputType = nil;
if ([returnTypeStr isEqualToString:@"i"]) {
outputType = @"%d";
} else if ([returnTypeStr isEqualToString:@"d"]) {
outputType = @"%f";
} else {
outputType = @"%@";
}
NSString *preStr = [NSString stringWithFormat:@"property name:%%@, value: %@", outputType];
NSLog(preStr, propertyName, [pBitch performSelector:NSSelectorFromString(propertyName)]);
}
// 获取所有实例方法
unsigned int methodCount;
Method *methodList = class_copyMethodList([pBitch class], &methodCount);
for (int i=0; i<methodCount; i++) {
Method method = methodList[i];
NSLog(@"method name: %@, encoding type: %@", NSStringFromSelector(method_getName(method)), [NSString stringWithUTF8String:method_getTypeEncoding(method)]);
}
// 获取所有类方法
unsigned int methodCount2;
Class metaClass = objc_getMetaClass(class_getName([pBitch class]));
Method *methodList2 = class_copyMethodList(metaClass, &methodCount2);
for (int i=0; i<methodCount2; i++) {
Method method = methodList2[i];
NSLog(@"class method name: %@, encoding type: %@", NSStringFromSelector(method_getName(method)), [NSString stringWithUTF8String:method_getTypeEncoding(method)]);
}
// 动态添加一个实例方法
// [pBitch sayAh]; // compile error
if ([pBitch respondsToSelector:@selector(sayAh)]) {
[pBitch performSelector:@selector(sayAh)];
} else {
NSLog(@"The bitch doesn't say Ah!");
}
NSLog(@"After teaching...");
class_addMethod([pBitch class], @selector(sayAh), (IMP)sayAhName, "v@:");
if ([pBitch respondsToSelector:@selector(sayAh)]) {
[pBitch performSelector:@selector(sayAh)];
}
// 替换方法实现
[pBitch sayHello];
IMP imp = class_getMethodImplementation(self, @selector(sayFuckMeImp));
class_replaceMethod([pBitch class], @selector(sayHello), (IMP)imp, method_getTypeEncoding(class_getInstanceMethod([pBitch class], @selector(sayHello))));
[pBitch sayHello];
// 动态创建一个类
Class GodnessClass = objc_allocateClassPair([NSObject class], "PCGodness", 0);
class_addMethod(GodnessClass, @selector(bless), class_getMethodImplementation(self, @selector(blessImp)), "v@:");
objc_registerClassPair(GodnessClass);
id godness = [[GodnessClass alloc] init];
[godness performSelector:@selector(bless)];
}
void sayAhName(id self, SEL _cmd) {
PCBitch *b = (PCBitch *)self;
NSLog(@"Ah~, call me %@ baby~", b.name);
}
- (void)sayFuckMeImp {
NSLog(@"Come on, fuck me baby!");
}
- (void)blessImp {
NSLog(@"Godness bless you, kid.");
}
@end