//
// 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

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

  1. 22.编写一个类A,该类创建的对象可以调用方法showA输出小写的英文字母表。然后再编写一个A类的子类B,子类B创建的对象不仅可以调用方法showA输出小写的英文字母表,而且可以调用子类新增的方法showB输出大写的英文字母表。最后编写主类C,在主类的main方法 中测试类A与类B。

    22.编写一个类A,该类创建的对象可以调用方法showA输出小写的英文字母表.然后再编写一个A类的子类B,子类B创建的对象不仅可以调用方法showA输出小写的英文字母表,而且可以调用子类新增的方法sh ...

  2. Java基础-接口.编写2个接口:InterfaceA和InterfaceB;在接口InterfaceA中有个方法void printCapitalLetter();在接口InterfaceB中有个方法void printLowercaseLetter();然 后写一个类Print实现接口InterfaceA和InterfaceB,要求 方法 实现输出大写英文字母表的功能,printLowerca

    #34.编写2个接口:InterfaceA和InterfaceB:在接口InterfaceA中有个方法void printCapitalLetter():在接口InterfaceB中有个方法void ...

  3. 常见iOS面试题 之 怎么判断一个类是否遵循某个协议

    答案: 使用方法conformsToProtocol. 调用例子: BOOL isConform = [Student conformsToProtocol:@protocol(UIScrollVie ...

  4. JVM如何加载一个类的过程,双亲委派模型中有哪些方法

    1.类加载过程:加载.验证.准备.解析.初始化   加载   在加载阶段,虚拟机主要完成三件事: 1.通过一个类的全限定名来获取定义此类的二进制字节流. 2.将这个字节流所代表的静态存储结构转化为方法 ...

  5. 13.首先,编写一个类ChongZai,该类中有3个重载的方法void print();其次, 再编写一个主类来测试ChongZai类的功能。

    package java1; //计算器 public class Jisuanqi { //属性 //型号,品牌等 //重载 //1.方法同名不同参 //2.返回类型和重载无关 //3.多态的一种表 ...

  6. 首先,编写一个类ChongZai,该类中有3个重载的方法void print();其次, 再编写一个主类来测试ChongZai类的功能

    //计算器 jisuanqi jsq=new jisuanqi(); System., )); System., , )); System.out.println("2.3和4.5 中最大的 ...

  7. 编写一个类A,该类创建的对象可以调用方法f输出小写的英文字母表。然 后再编写一个A类的子类B,要求子类B必须继承类A的方法f(不允许重写), 子类B创建的对象不仅可以调用方法f输出小写的英文字母表,而且可以调用子 类新增的方法g输出大写的英文字母表。最后编写主类C,在主类的main方法 中测试类A与类B。

    package zimu; public class A { public void f() { for (int i = 97; i <123; i++) { System.out.print ...

  8. iOS runtime 初步学习

    注: 在Xocde5之后, 使用运行时方法需要进行2步设置1. 在Build Setting中搜索'msg', 设置'Strict Checking' 为 NO2. 使用需要导入头文件 #import ...

  9. java一个类 继承HttpServlet 和实现Servlet区别

    java一个类 继承HttpServlet 和实现Servlet区别 servlet 是一个接口,如果实现这个接口,那么就必须实现接口里面定义的所有方法 而HttpServlet实现了servlet接 ...

随机推荐

  1. html5.0学习记录(一)——可拖动视频播放器

    最近自己在重新学习html5新特性,了解到有视频标签和拖动标签,于是自己用这两个特性写了一个小demo,主要功能就是可以通过拖动视频来直接播放.效果图如下: 页面使用了<video>标签和 ...

  2. uvm_factory——我们的工厂(三)

    现在让我们回过头来想想factory 是用来干什么,它做了什么? fantory就是生产uvm_object 和 uvm_component.用factory 生产和用SV直接new有什么区别了? f ...

  3. js数组去重方法包括Es6(方法有很多,但是需要考虑兼容性和数据类型场景)

    1.Es6提供的方法 <script type="text/javascript"> //ES6里新添加了两个方法,set(set是一种新的数据结构,它可以接收一个数组 ...

  4. dataSource' defined in class path resource [org/springframework/boot/autocon

    spring boot启动的时候抛出如下异常: dataSource' defined in class path resource [org/springframework/boot/autocon ...

  5. Go 1.4 正式版发布,官方正式支持 Android

    Go 1.4 正式发布啦,是第五个 Go 的稳定版本,与上一个稳定版本 Go 1.3 相隔 6 个月.Go 1.4 包括一些小的语言改进,支持更多的操作系统和处理器架构:改进了工具链和库.同时,Go ...

  6. vector的基本用法

    #include<iostream> #include<vector> #include<algorithm> using namespace std; int m ...

  7. 换个语言学一下 Golang (5)——运算符

    运算符用于在程序运行时执行数学或逻辑运算. Go 语言内置的运算符有: 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 其他运算符 接下来让我们来详细看看各个运算符的介绍. 算术运算符 下表 ...

  8. SniperOj-shorter-shellcode-x86

    shell-storm 这里可以有一些可以用的shellcode,不过自己写才是biner的骄傲 /奋斗 0x00 不会写shellcode(和一条咸鱼有什么区别/哭) 0x01 这题目前有俩种解法 ...

  9. mongodb测试类

    public class MongoManager { private static final String MONGO_DBNAME="local"; private stat ...

  10. x220 OS X 10.10.4安装

    变色龙安装过程: 1.使用磁盘助手将按照盘写入独立的磁盘分区(AF格式,就是Apple的HPS格式): 2.安装启动时,用-v -f -x参数,分别为显示信息.重新build系统驱动.安全模式: 3. ...