1.定义一盒ZBJPerson类
@interface ZBJPerson : NSObject
@property (nonatomic, copy) NSString *name;
- (void)logName;
- (void)logSomething;
@end
#import "ZBJPerson.h"
@interface ZBJPerson()
@property(nonatomic, strong) NSNumber *weight;
@end
@implementation ZBJPerson
- (void)logName {
NSLog(@"name:%@",_name);
}
- (void)logSomething {
NSLog(@"something");
}
@end
2.在ZBJRuntimeExample尝试交互logName实现。
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface ZBJRuntimeExample : NSObject
- (void)exchangeImplementations;
@end
#import "ZBJRuntimeExample.h"
#import <objc/runtime.h>
#import "ZBJPerson.h"
@interface ZBJRuntimeExample()
@property(nonatomic, strong) ZBJPerson *person;
@property (nonatomic, copy) NSString *name;
@end
@implementation ZBJRuntimeExample
- (instancetype)init {
self = [super init];
if (self) {
_person = [ZBJPerson new];
}
return self;
}
- (void)logName {
// NSLog(@"my name is :%@", _person.name);//会crash
// NSLog(@"my name is :%@", self.name);//输出结果 my name is :xxx
NSLog(@"my name is :%@", [self valueForKey:@"_name"]);
// [self logSomething];//直接报错,无法编译通过
[self performSelector:@selector(logSomething)];
}
- (void)exchangeImplementations {
_person.name = @"xxx";
self.name = @"123";
Method oriMethod = class_getInstanceMethod(_person.class, @selector(logName));
Method curMethod = class_getInstanceMethod(self.class, @selector(logName));
method_exchangeImplementations(oriMethod, curMethod);
[_person logName];
}
@end
注意方法交换以后,ZBJRuntimeExample的logName方法里面不能使用ZBJRuntimeExample的属性和方法。应该使用ZBJPerson的属性和方法,此时logName的self是ZBJPerson而不是ZBJRuntimeExample。属性可以用KVC,方法可以用performSelector。