美文网首页
NSProxy 实现“多继承”

NSProxy 实现“多继承”

作者: bonoCat | 来源:发表于2017-08-28 18:47 被阅读136次

之前有在YYWeakProxy看到过 NSProxy 使用,可以解决NSTimer 对 target 是强引用的问题。主要使用 NSProxy 对 target 进行消息转发,并不会对 target 造成引用关系。那么 NSProxy 能对多个对象方法进行转发,就是 NSProxy 具有了多个对象的方法,可以实现“多继承”。

NSProxy是什么?

根据官方文档的解释,NSProxy是一个抽象超类,主要用于将一个信息,转发到一个真实对象中。

消息转发

在NSProxy中有这么一种转发方法:方法签名转发

- (void)forwardInvocation:(NSInvocation *)invocation;
- (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel NS_SWIFT_UNAVAILABLE("NSInvocation and related APIs not available");

可以通过消息转发的方式,让抽象类将消息转发的真实类中。不过很快发现了一个问题,这些方法并不属于 Proxy ,不能直接调用。他们之间需要有一个桥梁来沟通,可以使用协议来约定,这样就可以直接进行调用操作。下面看下具体的实现:

实现“多继承”

Person.h

#import <Foundation/Foundation.h>

@protocol PersonPtotocol <NSObject>

@property (nonatomic, copy) NSString *name;

- (NSString *)getPersonInfo;

@end

@interface Person : NSObject<PersonPtotocol>

@end

Person.m

#import "Person.h"

@implementation Person

@synthesize name = _name;

- (NSString *)getPersonInfo
{
    return [NSString stringWithFormat:@"person name: %@", _name];
}

@end

由与当前类中并没有 NSString *name 和 getPersonInfo方法,所以需要在实现文件中实现,这样Person才真正具有这两个方法。

BDExtends.m

Proxy中并不包含该方法,会直接进行方法签名,但是缺少签名的对象,所以就需要提前获取target,当然可以直接通过方法名称来确定target,不过比较麻烦,我这里就使用字典来表示他们之间的关系。

- (instancetype)initExtends:(NSArray<NSString *> *)extends
{
    NSMutableDictionary *tempMethodList = @{}.mutableCopy;
    
    [extends enumerateObjectsUsingBlock:^(NSString *_Nonnull objString, NSUInteger idx, BOOL * _Nonnull stop) {
        
        Class objClass = NSClassFromString(objString);
    
        NSString *des = [NSString stringWithFormat:@"can not find the class of %@", objString];
        NSAssert(objString != nil, des);
        
        
        id obj = [[objClass alloc] init];
        
        unsigned int numberOfMethods = 0;

        Method *methodList = class_copyMethodList(objClass, &numberOfMethods);
        
        for (int i = 0 ; i < numberOfMethods; i++) {
            
            Method tempMethod = methodList[i];
            
            SEL tempSel = method_getName(tempMethod);
            
            const char *tempMethodName = sel_getName(tempSel);
            
            [tempMethodList setObject:obj forKey:[NSString stringWithUTF8String:tempMethodName]];
    
        }
        
    }];
    
    self.methodList = [[NSDictionary alloc] initWithDictionary:tempMethodList copyItems:NO];
    
    return self;
}

获取target 和 act ,使用 class_copyMethodList 获取所有的方法列表,然后关联到自己创建的target上去,后面也可以使用方法名称直接获取对应的target,也是很不错的选择。


- (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
 NSString *methodName = NSStringFromSelector(sel);
    
    id target = [self.methodList valueForKey:methodName];
    
    if (target && [target respondsToSelector:sel])
    {
        return [target methodSignatureForSelector:sel];
    }
}

通过使用 methodSignatureForSelector ,获取了NSMethodSignature,方法也就进行了重新签名,下面就是转发实现:


- (void)forwardInvocation:(NSInvocation *)invocation
{
    SEL sel = invocation.selector;
    
    NSString *methodName = NSStringFromSelector(sel);
    
    id target = [self.methodList valueForKey:methodName];
    
    if (target && [target respondsToSelector:sel]) {
        
        [invocation invokeWithTarget:target];
    }

}

主要是通过 NSInvocation 给真实对象转发消息,获取target来进行方法转发。

最后看下demo

相关文章

  • NSProxy 实现“多继承”

    之前有在YYWeakProxy看到过 NSProxy 使用,可以解决NSTimer 对 target 是强引用的问...

  • NSProxy实现伪多继承

    Objective-C是不支持多继承的,但是基于消息转发机制我们可以使用NSProxy来实现伪多继承。 1.关于N...

  • 协议和 NSProxy 实现多继承

    OC 中一个类只有一个父类, 这就是单一继承, 但是我们可以用协议和 NSProxy 实现多继承 先说协议, 协议...

  • iOS NSProxy使用

    简介:通过NSProxy 可以实现类的"伪多继承",demo中KLProxy通过拦截方法修改了cat和dog本来的...

  • NSProxy 使用总结

    NSProxy是一个虚类。它有什么用处呢?OC中类是不支持多继承的,要想实现多继承一般是有protocol的方式,...

  • iOS:NSProxy

    OC 中一个类只有一个父类,这就是单一继承,但是我们可以用协议和NSProxy实现多继承。 1、 protocol...

  • 记录NSObject 的关系

    NSObject的关系 NSProxy 没有继承NSObject,只实现了NSObject的协议,所以NSProx...

  • OC中如何实现”多继承“,(NSProxy,Protocol)

    OC 中一个类只有一个父类 但是我们可以用协议和 NSProxy 实现多继承 1. protocol 先说协议 比...

  • 关于 iOS 实现多继承的补充

    刚刚看到一篇文章介绍的是关于iOS多继承的实现,作者也是用NSProxy实现,但是和我之前的有些不一样,在这里做个...

  • 详解NSProxy

    一、概述 NSProxy是少有的没有从NSObject类继承的类,它实现了NSObject协议。其日常使用不多,但...

网友评论

      本文标题:NSProxy 实现“多继承”

      本文链接:https://www.haomeiwen.com/subject/ywwgdxtx.html