//
// 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. 自定义消息中如果需要定义WPARAM和LPARAM,该怎么使用和分配?

    写Windows程序不可避免要使用自定义的消息,也就是从WM_USER开始定义的消息.在定义一个消息后,往往我们还要定义针对该消息的WPARAM甚至是LPARAM.WPARAM和LPARAM是什么,可 ...

  2. socket使用非阻塞connect

    在使用tcp的connect调用时,默认是使用阻塞方式,当服务器当前不可用时,connect会等待(内部在重试?)直到超时时间到达,而这个超时时间是系统内核规定的,不能使用setSocketOpt来设 ...

  3. Linux的安装与配置

    PS:本文适合刚刚了解Linux系统,并想要学习Linux系统的一些基本操作的同学.只要按如下方法安装配置好,就可以在自己的电脑上使用Linux系统了. 一.安装前的准备 1.下载并安装VMware ...

  4. springMVC中ajax和后台数据格式错误

    前台ajax: $.ajax("${pageContext.request.contextPath}/hello",// 发送请求的URL字符串. { dataType : &qu ...

  5. 批处理文件 bat

    删除D盘的所有文件:del /a /f /q d:\*.* 删除指定目录的指定扩展名的文件:del /a /f /q 目录:\*.jpg 删除当前目录下的指定扩展名的文件(指定扩展名为jpg):del ...

  6. 洛谷 P2253 好一个一中腰鼓!

    题目背景 话说我大一中的运动会就要来了,据本班同学剧透(其实早就知道了),我萌萌的初二年将要表演腰鼓[喷],这个无厘头的题目便由此而来. Ivan乱入:“忽一人大呼:‘好一个安塞腰鼓!’满座寂然,无敢 ...

  7. CNNs 在图像分割中应用简史: 从R-CNN到Mask R-CNN

    作者:嫩芽33出处:http://www.cnblogs.com/nenya33/p/6756024.html 版权:本文版权归作者和博客园共有 转载:欢迎转载,但未经作者同意,必须保留此段声明:必须 ...

  8. OCR/Vote disk 维护操作: (添加/删除/替换/移动) (文档 ID 1674859.1)

    适用于: Oracle Database - Enterprise Edition - 版本 10.2.0.1 到 11.2.0.1.0 [发行版 10.2 到 11.2]本文档所含信息适用于所有平台 ...

  9. 解决因为手机设置字体大小导致h5页面在webview中变形的BUG

    首先,我们做了一个H5页面,在各种手机浏览器中打开都没问题.我们采用了rem单位进行布局,通过JS来动态计算网页的视窗宽度,动态设置html的font-size,一切都比较完美. 这时候,你自信满满的 ...

  10. 洛谷P1001 A+B Problem

    这道题…………还是很简单!!! code: #include <iostream> #include <cstdio> using namespace std; int mai ...