//
// 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. Android recyclerview 只显示一行 宽度不适配

    最近学习recyclerview 遇到的问题 1.宽度不适配 正确写法 LayoutInflater.from(context).inflate(R.layout.item_view,parent,f ...

  2. Cairo Drawing Model

    Cairo Drawing Model Cairo是一个强力的2D绘图库. Destination 是你最终绘图的目标, 可以是一系列Pixel或者绑定到SVG或PDF文件上. Source 是实际在 ...

  3. UIWebView与JavaScript相互调用

    UIWebView与JavaScript的那些事儿 UIWebView是IOS SDK中渲染网面的控件,在显示网页的时候,我们可以hack网页然后显示想显示的内容.其中就要用到javascript的知 ...

  4. 中国剩余定理&Lucas定理&按位与——hdu 5446

    链接: hdu 5446 http://acm.hdu.edu.cn/showproblem.php?pid=5446 题意: 给你三个数$n, m, k$ 第二行是$k$个数,$p_1,p_2,p_ ...

  5. ping 不通。无法访问目标主机

    台式机 使用无线网卡  又登录了VPN 有时候访问不了局域网内的主机 解决方案  添加路由即可 window+R 打开运行 输入cmd  然后输入 route add 10.16.1.89 10.13 ...

  6. 爬虫_python3_requests_2

    pip install requests 进行简单的操作 发送一个get请求 # 发送请求 import requests response = requests.get('http://httpbi ...

  7. hash 散列表

    一个字符串的hash值: •现在我们希望找到一个hash函数,使得每一个字符串都能够映射到一个整数上 •比如hash[i]=(hash[i-1]*p+idx(s[i]))%mod •字符串:abc,b ...

  8. SQLyog连接数据库 提示错误plugin caching_sha2_password could not be loaded

    1.打开mysql cmd 2.执行语句 ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER; # ...

  9. shell脚本,逻辑结构题练习。

    awk '/5/{a=1}!a' file2结果:1234解释:第一行 /5/不匹配跳过{a=1},继续!a,此时a没有值属于假取反为真,故输出第一行 第二行 /5/不匹配跳过{a=1},继续!a,此 ...

  10. ios之UIImageView

    UIImageView,顾名思义,是用来放置图片的.使用Interface Builder设计界面时,当然可以直接将控件拖进去并设置相关属性,这就不说了,这里讲的是用代码. 1.创建一个UIImage ...