当前位置: 首页 > 工具软件 > Dodo-iOS > 使用案例 >

iOS-runtime-根据协议名调某一个类有与协议里面放的相同的方法

欧阳飞章
2023-12-01
//
//  ViewController.m
//  ObserverTrampoline
//
//  Created by Rob Napier on 9/7/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import "ViewController.h"
#import "RNObserverManager.h"

@protocol MyProtocol <NSObject>
@optional
- (void)doSomething;


- (void)dodo;

@end

@interface MyClass : NSObject <MyProtocol>
@end

@implementation MyClass

- (void)doSomething {
  NSLog(@"doSomething :%@", self);
}

@end


@interface MyClass1 : NSObject
@end

@implementation MyClass1

- (void)dodo1 {
    NSLog(@"dodo1 :%@", self);
}

- (void)dodo {
    NSLog(@"dodo 要走");
}

@end

@implementation ViewController
//@synthesize observerManager=trampoline_;

- (void)viewDidLoad {
  [super viewDidLoad];
    
  //这样就可以执行一些事情,比如一个类遵守某个协议,它可以直接调这个协议执行那个类里面写的something
    
  NSSet *observers = [NSSet setWithObjects:[MyClass new],[MyClass1 new], nil];

  self.observerManager = [[RNObserverManager alloc] 
                          initWithProtocol:@protocol(MyProtocol) 
                          observers:observers];
  
  [self.observerManager doSomething];
  [self.observerManager dodo];

}

@end

实现的方法

#import "RNObserverManager.h"

@interface RNObserverManager ()
@property (nonatomic, readonly, strong) NSMutableSet *observers;
@property (nonatomic, readonly, strong) Protocol *protocol;
@end

@implementation RNObserverManager
//协议 集合
- (id)initWithProtocol:(Protocol *)protocol
             observers:(NSSet *)observers {
    if ((self = [super init])) {
        _protocol = protocol;
        _observers = [NSMutableSet setWithSet:observers];
    }
    return self;
}

- (void)addObserver:(id)observer {
  NSAssert([observer conformsToProtocol:self.protocol], 
           @"Observer must conform to protocol.");
    [self.observers addObject:observer];
}

- (void)removeObserver:(id)observer {
    [self.observers removeObject:observer];
}


//NSObject --------
//这个函数让重载方有机会抛出一个函数的签名,再由后面的forwardInvocation:去执行。
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
    NSMethodSignature *
  result = [super methodSignatureForSelector:sel];
  if (result) {
   return result; 
  }
  
  // Look for a required method
    struct objc_method_description desc = 
             protocol_getMethodDescription(self.protocol,
                                           sel, YES, YES);
    if (desc.name == NULL) {
        // Couldn't find it. Maybe it's optional
        desc = protocol_getMethodDescription(self.protocol,
                                         sel, NO, YES);
    }
  
    if (desc.name == NULL) {
    // Couldn't find it. Raise NSInvalidArgumentException
        [self doesNotRecognizeSelector:sel];
        return nil;
  }
  
  return [NSMethodSignature signatureWithObjCTypes:desc.types];
}

//真正执行从methodSignatureForSelector:返回的NSMethodSignature。在这个函数里可以将NSInvocation多次转发到多个对象中,这也是这种方式灵活的地方。(forwardingTargetForSelector只能以Selector的形式转向一个对象)

- (void)forwardInvocation:(NSInvocation *)invocation {
    SEL selector = [invocation selector];
    for (id responder in self.observers) {
        if ([responder respondsToSelector:selector]) {
            [invocation setTarget:responder];
            [invocation invoke];
        }
    }
}

参考:http://www.cnblogs.com/biosli/p/NSObject_inherit_2.html

http://blog.csdn.net/yiyaaixuexi/article/details/8970734

转载于:https://www.cnblogs.com/hxwj/p/4795637.html

 类似资料: