iOS-runtimeの一般的な方法の例
31393 ワード
#import
@interface Person : NSObject
@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *sex;
-(NSString *)sayName;
-(NSString *)saySex;
@end
- (void)viewDidLoad {
[super viewDidLoad];
self.person = [Person new];
_person.name = @"xiaoming";
NSLog(@"XiaoMing first answer is %@",self.person.name);
[self sayName];
}
- (void)sayName
{
unsigned int count = 0;
Ivar *ivar = class_copyIvarList([self.person class], &count);
for (int i = 0; i) {
Ivar var = ivar[i];
const char *varName = ivar_getName(var);
NSString *proname = [NSString stringWithUTF8String:varName];
if ([proname isEqualToString:@"_name"]) { //
object_setIvar(self.person, var, @"daming");
break;
}
}
NSLog(@"XiaoMing change name is %@",self.person.name);
}
- (void)viewDidLoad {
[super viewDidLoad];
self.person = [Person new];
[self sayFrom];
}
- (void)sayFrom
{
class_addMethod([self.person class], @selector(guess), (IMP)guessAnswer, "v@:");
if ([self.person respondsToSelector:@selector(guess)]) {
//Method method = class_getInstanceMethod([self.xiaoMing class], @selector(guess));
[self.person performSelector:@selector(guess)];
} else{
NSLog(@"Sorry,I don't know");
}
}
void guessAnswer(id self,SEL _cmd){
NSLog(@"function: guessAnswer");
NSLog(@"__%@__", NSStringFromSelector(_cmd));
}
- (void) guess{
NSLog(@"function: guess");
NSLog(@"__%@__", NSStringFromSelector(_cmd));
}
- (void)viewDidLoad {
[super viewDidLoad];
self.person = [Person new];
NSLog(@"%@",_person.sayName);
NSLog(@"%@",_person.saySex);
Method m1 = class_getInstanceMethod([self.person class], @selector(sayName));
Method m2 = class_getInstanceMethod([self.person class], @selector(saySex));
method_exchangeImplementations(m1, m2);
}
@interface Tool : NSObject
+ (instancetype)sharedManager;
- (NSString *)changeMethod;
- (void)addCount;
@end
#import "Tool.h"
@interface Tool ()
@property (nonatomic, assign) NSInteger count;
@end
@implementation Tool
+ (instancetype)sharedManager {
static Tool *_sInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sInstance = [[Tool alloc] init];
});
return _sInstance;
}
- (NSString *)changeMethod
{
return @"haha, ";
}
- (void)addCount
{
_count += 1;
NSLog(@" ------%ld", _count);
}
@end
- (void)viewDidLoad {
[super viewDidLoad];
// [self.person class],
Method m1 = class_getInstanceMethod([Person class], @selector(sayName));
Method m2 = class_getInstanceMethod([Tool class], @selector(changeMethod));
method_exchangeImplementations(m1, m2);
}
@implementation FiveViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(100, 100, 100, 100);
[button setTitle:@" " forState:UIControlStateNormal];
[button addTarget:self action:@selector(ButtonClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
- (void)ButtonClick
{
NSLog(@" ");
}
@end
#import
2、具体的な実装コード:
/** :MyObject */
//
#import
@interface MyObject : NSObject
@property(strong,nonatomic) NSString *string;
@property(strong,nonatomic) NSArray *array;
- (void)method1;
- (void)method2;
- (void)classMethod1;
@end
//
#import "MyObject.h"
#import
@interface MyObject (){
NSInteger _instance1;
NSString *_instance2;
}
@property(assign,nonatomic) NSInteger intrger;
- (void)method3WithArge1:(NSInteger)arge1 arge2:(NSString *)arge2;
@end
@implementation MyObject
-(void)classMethod1{
}
- (void)method1{
NSLog(@"cell Method1");
}
- (void)method2{
}
- (void)method3WithArge1:(NSInteger)arge1 arge2:(NSString *)arge2{
NSLog(@"arge1 %ld arge2 %@",arge1,arge2);
}
+ (BOOL)resolveInstanceMethod:(SEL)sel{
NSString *selector = NSStringFromSelector(sel);
if ([selector isEqualToString:@"method1"]) {
class_addMethod(self.class, @selector(method1), (IMP)functionForMethod1, "@:");
}
return [super resolveInstanceMethod:sel];
}
void functionForMethod1(id self,SEL _cmd){
NSLog(@"%@ %p",self,_cmd);
}
- (instancetype)forwardingTargetForSelector:(SEL)aSelector{
NSString *selector = NSStringFromSelector(aSelector);
if([selector isEqualToString:@"method2"]){
//return;
}
return [super forwardingTargetForSelector:aSelector];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation{
}
@end
/** */
#import
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//1.
// ViewController
NSLog(@"%s",class_getName([self class]));
//
//This is superClass 0x10f426da0 isa
NSLog(@"This is superClass %p",class_getSuperclass([self class]));
//
//Is MateClass 0
NSLog(@"Is MateClass %d",class_isMetaClass([self class]));
//
//848
size_t a = class_getInstanceSize([self class]);
NSLog(@"%ld",a);
unsigned int outCount = 0;
MyObject *objtect = [[MyObject alloc] init];
Class cls = objtect.class;
//
NSLog(@"Class name %s",class_getName(cls));
//
NSLog(@"SuperClass name %s",class_getName(class_getSuperclass(cls)));
//
NSLog(@"Is MetaClass %@",(class_isMetaClass(cls))?@"":@"NOT");
//
NSLog(@"MyObject size %ld",class_getInstanceSize(cls));
//
Ivar string = class_getInstanceVariable(cls, "_string");
if (string != NULL) {
NSLog(@"MyObject instance messge %s",ivar_getName(string));
}
//
objc_property_t *v = class_copyPropertyList(cls, &outCount);
for (NSInteger i = 0; i< outCount; i++) {
objc_property_t property = v[i];
NSLog(@"property is %s ",property_getName(property));
}
free(v);
//
Ivar *vars = class_copyIvarList(cls, &outCount);
for (NSInteger i =0; i< outCount; i++) {
Ivar ivar = vars[i];
NSLog(@"copyIvarList is %s is %ld",ivar_getName(ivar),i);
}
free(vars);
//
Method *methods = class_copyMethodList(cls, &outCount);
for (NSInteger i =0; i< outCount; i++) {
Method met = methods[i];
#pragma clang diagnostic ignored"-Wformat"
NSLog(@"Method is %s",method_getName(met));
}
free(methods);
// Format specifies type 'char *' but the argument has type 'SEL _Nonnull'
//
Method method = class_getInstanceMethod(cls,@selector(method1));
NSLog(@"Method name is %s",method_getName(method));
//
#pragma clang diagnostic ignored"-Wundeclared-selector"
NSLog(@"Have you method %d",class_respondsToSelector(cls, @selector(method3WithArge1:arge2:)));
// ,
IMP imp = class_getMethodImplementation(cls, @selector(method1));
imp();
//
#pragma clang diagnostic ignored" -Wunused-variable"
// : , objc_allocateClassPair objc_registerClassPair
// 1. MySubClass
// class, ,
Class myClass = objc_allocateClassPair(objtect.class, "MySubClass", 0);
// 2. ,
// : v@: v void @:
if( class_addMethod(myClass, @selector(mysubMethod1),(IMP)mysubMethod1, "v@:")){
class_replaceMethod(myClass, @selector(method1), (IMP)mysubMethod1,"v@:");
}
/*
3. NSSsting myString
size sizeof(NSString)
log2(sizeof(NSString*))
@encode(NSString*)
class_addIvar(class, , size, , )
*/
//
BOOL isd = class_addIvar(myClass, "_myString", sizeof(NSString *), log(sizeof(NSString *)), @encode(NSString *));
NSLog(@" %d",isd);
/*
T@encode(type) , V , , property_getAttributes
R readonly
C copy
& retain ARC strong
N nonatomic
G(name) getter=(name)
S(name) setter=(name)
D @dynamic
W weak
P
*/
//@T
objc_property_attribute_t type;
type.name = "T";
type.value = @encode(NSString *);
//copy
objc_property_attribute_t owership = {"C",""};
//nonatomic
objc_property_attribute_t oeership2 = {"N",""};
//V_
objc_property_attribute_t var = {"V","_myString"};
//
objc_property_attribute_t attributes[] = {type,owership,oeership2,var};
// myString , attributes
class_addProperty(myClass, "myString", attributes, 4);
unsigned int propertyCount;
objc_property_t * properties = class_copyPropertyList(myClass, &propertyCount);
for (int i = 0; i) {
NSLog(@" : %s",property_getName(properties[i]));
NSLog(@" : %s",property_getAttributes(properties[i]));
}
//
free(properties);
// objc_allocateClassPair
objc_registerClassPair(myClass);
id instance = [[myClass alloc] init];
[instance performSelector:@selector(mysubMethod1)];
[instance performSelector:@selector(method1)];
//
// , ,
//objc_disposeClassPair(myClass);
//
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
view.backgroundColor = [UIColor redColor];
[view setTapActionWithBlock:^{
NSLog(@"saAS");
}];
[self.view addSubview:view];
//SEL
//Objective-C , 、 , (Int ), SEL
//SEL ( , hash KEY ,
// ,
//sel : 0x104dd7735
/*
SEL:
sel_registerName
Objective-C @selector()
NSSelectorFromString()
*/
SEL sel1 = @selector(method1);
NSLog(@"sel : %p", sel1);
}
static void mysubMethod1(id self,SEL _cmd){
NSLog(@" ");
}
@end
転載先:https://www.cnblogs.com/xujinzhong/p/8549132.html