1. OC 语言的优缺点
优点:
- category
- posing
- 动态特性
runtime: 函数实现 IMP 动态绑定, resolve
- 动态特性
- 指标计算
- 弹性讯息传递
- 不是一个过度复杂的 C 衍生语言
- Objective_C 与 C++可以混编;
缺点:
- Objective_C 与 C++可以混编;
- 不支持元命名空间
- 不支持运算符重载
- 不支持多重继承
- 使用动态运行时类型, 所有方法都是函数调用, 所有很多编译时优化方案, 都用不到(如内联函数), 性能低劣!
2. OC 消息发送机制
// 1.方法调用
ViewController *VC = [ViewController new];
[VC testCommand];
// 2. 通过objc_msgSend 函数调用
ViewController *VC1 = ((ViewController *(*)(id, SEL))objc_msgSend)([ViewController class], @selector(alloc));
VC1 = ((ViewController *(*)(id, SEL))objc_msgSend)(VC1, @selector(init));
((ViewController *(*)(id, SEL))objc_msgSend)(VC1, @selector(testCommand));
// 3. 通过 performSelector map 映射
[VC performSelector:@selector(testCommand) withObject:@"132"];
3. OC 消息转发机制
@interface ADDIMP :NSObject
- (void)testCommand1;
@end
@implementation ADDIMP
- (void)testCommand1 {
NSLog(@"%s\n我是新的 IMP ", __FUNCTION__);
}
@end
@interface ViewController ()
// 为了能编译通过, 在此声明这个方法
- (void)testCommand1;
@end
@implementation ViewController
// 自定义函数 IMP
void dynamicMethodIMP(id self, SEL _cmd)
{
printf("%s", __func__);
}
// 1. 动态方法解析, 通过 runtime 添加方法 IMP
+ (BOOL)resolveInstanceMethod:(SEL)sel {
NSLog(@"sel =%@", NSStringFromSelector(sel));
// if (sel == NSSelectorFromString(@"testCommand1")) {
// NSLog(@"%s\n绑定我自己的 IMP ", __FUNCTION__);
// class_addMethod(self, sel, (IMP)dynamicMethodIMP, "v@:");
// return YES;
// }
return [super resolveInstanceMethod:sel];
}
// 2. 快速消息转发
- (id)forwardingTargetForSelector:(SEL)aSelector {
NSLog(@"%s\n绑定别人的 IMP ", __FUNCTION__);
// if (aSelector == NSSelectorFromString(@"testCommand1")){
//
// return [ADDIMP new];
// }
return [super forwardingTargetForSelector:aSelector];
}
// 3. 标准的消息转发
// 3.1 方法签名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
if (aSelector == NSSelectorFromString(@"testCommand1")){
NSMethodSignature *sign = [NSMethodSignature signatureWithObjCTypes:"v@:"];
return sign;
}
return [super methodSignatureForSelector:aSelector];
}
// 3.2 开始转发
- (void)forwardInvocation:(NSInvocation *)anInvocation {
SEL aSelector = [anInvocation selector];
ADDIMP *add = [ADDIMP new];
if ([add respondsToSelector:aSelector])
[anInvocation invokeWithTarget:add];
else
[super forwardInvocation:anInvocation];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self testCommand1];
}
@end
4. OC 模拟多重继承
// SubClass.h
#import <Foundation/Foundation.h>
@protocol ClassOne_protocol
- (void)ClassOneString:(NSString *)string;
@end
@interface ClassOne : NSObject <ClassOne_protocol>
@end
@protocol ClassTwo_protocol
- (void)ClassTwoString:(NSString *)string;
@end
@interface ClassTwo : NSObject<ClassTwo_protocol>
@end
@interface SubClass : NSProxy <ClassOne_protocol, ClassTwo_protocol>
+ (instancetype)subClass;
@end
// SubClass.m
#import "SubClass.h"
#import <objc/message.h>
@implementation ClassOne
- (void)ClassOneString:(NSString *)string {
NSLog(@"\n%s\n ClassOneString\n", __FUNCTION__);
}
@end
@implementation ClassTwo
- (void)ClassTwoString:(NSString *)string {
NSLog(@"\n%s\n ClassTwoString\n", __FUNCTION__);
}
@end
@implementation SubClass{
NSMutableDictionary *_methodMap;
}
+ (instancetype)subClass {
return [[SubClass alloc] init];
}
- (instancetype)init {
_methodMap = [NSMutableDictionary dictionary];
[self registerMethodsWithTarget:[ClassOne new]];
[self registerMethodsWithTarget:[ClassTwo new]];
return self;
}
- (void)registerMethodsWithTarget:(id)target {
unsigned int count = 0;
// 获取方法列表
Method *methodList = class_copyMethodList([target class], &count);
// 依次添加方法
for (NSInteger i = 0; i < count; i++) {
Method method = methodList[i];
SEL sel = method_getName(method);
[_methodMap setObject:target forKey:NSStringFromSelector(sel)];
}
// dealloc 中不会提醒
free(methodList);
}
// 标准的消息转发机制, 动态添加方法
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
// 1. 获取方法名
NSString *methodName = NSStringFromSelector(aSelector);
// 2. 方法目标对象
id target = [_methodMap objectForKey:methodName];
// 3. 开始对方法签名
if(target && [target respondsToSelector:aSelector]) {
return [target methodSignatureForSelector:aSelector];
}
return [super methodSignatureForSelector:aSelector];
}
// 开始转发
- (void)forwardInvocation:(NSInvocation *)anInvocation {
SEL sel = anInvocation.selector;
NSString *methodName = NSStringFromSelector(sel);
id target = [_methodMap objectForKey:methodName];
if (target && [target respondsToSelector:sel]) {
// 执行
[anInvocation invokeWithTarget:target];
}else
[super forwardInvocation:anInvocation];
}
@end
// 测试
SubClass *subClass = [SubClass subClass];
[subClass ClassOneString:@"111111111"];
[subClass ClassTwoString:@"222222222"];