http://yang152412.blog.163.com/blog/static/175861582201332321351862/

一、UISignal的工作模式

1、发送Signal,比如从ViewController的loadView和ViewDidLoad方法,Button的touch方法,view更改frame的方法。

在框架中, 系统的 loadView和ViewDidLoad方法,Button的touch方法 大部分都在 封装的 类中实现,子类没有实现,通过signal来回调到子类。

[self sendUISignal:BeeUIButton.TOUCH_DOWN];

2、在UIView的扩展类或者 UIViewController扩展类 中 生成 对应的Signal

- (BeeUISignal *)sendUISignal:(NSString *)name

{

return [self sendUISignal:name withObject:nil from:self];

}

- (BeeUISignal *)sendUISignal:(NSString *)name withObject:(NSObject *)object

{

return [self sendUISignal:name withObject:object from:self];

}

- (BeeUISignal *)sendUISignal:(NSString *)name withObject:(NSObject *)object from:(id)source{

BeeUISignal * signal = [[[BeeUISignal alloc] init] autorelease];

if ( signal )

{

NSString * selName = self.tagString.lowercaseString;

selName = [selName stringByReplacingOccurrencesOfString:@"-" withString:@"_"];

// selName = [selName stringByReplacingOccurrencesOfString:@":" withString:@"_"];

signal.preSelector = selName; // v0.3.0 new feature, signal binding

signal.source = source ? source : self;

signal.target = self;

signal.name = name;

signal.object = object;

[signal send];

}

return signal;

}

2、[signal send];  生成的signal 调用send方法,来传递 该signal

在 send 方法里面,解析 传递的 name,判断source 是不是 发送消息类的子类。更新 foreign, _callPath,_sendTimeStamp,_reach,_jump 等属性。然后调用 routes方法。

3、在 - (void)routes;  方法里面,根据 signal 的 name,target,判断 target 是否实现了 响应方法,

NSString * clazz = (NSString *)[array objectAtIndex:1];

NSString * method = (NSString *)[array objectAtIndex:2];

NSObject * targetObject = _target;

if ( [_target isKindOfClass:[UIView class]] )

{

UIViewController * viewController = [(UIView *)_target viewController];

if ( viewController )

{

targetObject = viewController;

}

}

#if defined(__BEE_SELECTOR_STYLE2__) && __BEE_SELECTOR_STYLE2__

{

NSString * selectorName;

SEL selector;

selectorName = [NSString stringWithFormat:@"handleUISignal_%@_%@:", clazz, method];

selector = NSSelectorFromString(selectorName);

if ( [targetObject respondsToSelector:selector] )

{

[targetObject performSelector:selector withObject:self];

return;

}

selectorName = [NSString stringWithFormat:@"handleUISignal_%@:", clazz];

selector = NSSelectorFromString(selectorName);

if ( [targetObject respondsToSelector:selector] )

{

[targetObject performSelector:selector withObject:self];

return;

}

}

#endif // #if defined(__BEE_SELECTOR_STYLE2__) && __BEE_SELECTOR_STYLE2__

#if defined(__BEE_SELECTOR_STYLE1__) && __BEE_SELECTOR_STYLE1__

{

NSString * selectorName;

SEL selector;

selectorName = [NSString stringWithFormat:@"handle%@:", clazz];

selector = NSSelectorFromString(selectorName);

if ( [targetObject respondsToSelector:selector] )

{

[targetObject performSelector:selector withObject:self];

return;

}

 

如果都没有实现,则 遍历 父类 有没有实现,如果父类没有实现,则 判断 _target 是否响应 handleUISignal:方法,如果实现(应该总是有的,因为 所有view控件的父类总是UIView,而框架 扩展UIView类:UIView(BeeUISignal) 里面实现了方法,

- (void)handleUISignal:(BeeUISignal *)signal

{

if ( self.superview )

{

[signal forward:self.superview];

}

else

{

signal.reach = YES;

#if defined(__BEE_DEVELOPMENT__) && __BEE_DEVELOPMENT__

CC( @"[%@] > %@", signal.name, signal.callPath );

#endif // #if defined(__BEE_DEVELOPMENT__) && __BEE_DEVELOPMENT__

}

}

在判断当前 view有没有 父view,如果有,则调用signal的 - (BOOL)forward:(id)target; 即路由往前走了一步,找到了view。然后forward方法里面继续调用 routes 方法。形成 递归 路径,例如 BeeUIButton的 touch时间的 callPath就是:

BeeUIButton 的触法事件 Signal 的 callPath,从上到下 依次 遍历,直到找到 实现响应方法。

[signal.BeeUIButton.TOUCH_DOWN] > BeeUIButton > Lesson2View2 > Lesson2View1 > BeeUIBoardView > Lesson2Board

 

和UIView+BeeUISignal 类似,UIVIewController的扩展类 也实现了 最基本的 响应方法,一遍 BeeUISignal的 routes方法 最后的判断做处理。只是没有了 判断 view是否有 superview。

- (void)handleUISignal:(BeeUISignal *)signal

{

signal.reach = YES;

#if defined(__BEE_DEVELOPMENT__) && __BEE_DEVELOPMENT__

CC( @"[%@] > %@", signal.name, signal.callPath );

#endif // #if defined(__BEE_DEVELOPMENT__) && __BEE_DEVELOPMENT__

}

4、比较关键的参数 name,和响应方法的命名。
name的组成:  signal.(类名).(消息名/方法名) 。
响应方法的命名: 
- (void)handleUISignal_(发送消息的类名):(BeeUISignal *)signal;
内部都调用 super。在 super里面把 signal的reach赋YES,标识达到末尾
 
5、如何自己添加 signal,以button为例:
在头文件 中 声明: AS_SIGNAL( TEST )
实现:@implementation Lesson2View2

DEF_SIGNAL( TEST )

@end

添加:
_innerView = [[BeeUIButton alloc] initWithFrame:CGRectToBound(frame)];

[_innerView addSignal:Lesson2View2.TEST forControlEvents:UIControlEventTouchUpInside];

 
 
6、UISignal 就是将 一个 事件 从上往下 依次传递,直到找到对应的 相应方法的类 为止。

BeeFramework 笔记 四(UISignal 总结)的更多相关文章

  1. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  2. 《MFC游戏开发》笔记四 键盘响应和鼠标响应:让人物动起来

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9327377 作者:七十一雾央 新浪微博:http:// ...

  3. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  4. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  5. Java学习笔记四---打包成双击可运行的jar文件

    写笔记四前的脑回路是这样的: 前面的学习笔记二,提到3个环境变量,其中java_home好理解,就是jdk安装路径:classpath指向类文件的搜索路径:path指向可执行程序的搜索路径.这里的类文 ...

  6. Java加密与解密笔记(四) 高级应用

    术语列表: CA:证书颁发认证机构(Certificate Authority) PEM:隐私增强邮件(Privacy Enhanced Mail),是OpenSSL使用的一种密钥文件. PKI:公钥 ...

  7. Learning ROS for Robotics Programming Second Edition学习笔记(四) indigo devices

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  8. Typescript 学习笔记四:回忆ES5 中的类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  9. Django开发笔记四

    Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.邮箱激活 users app下,models.py: ...

随机推荐

  1. Numpy 索引及切片

    1.一维数组的索引及切片 ar = np.arange(20) print(ar) print(ar[4]) print(ar[3:6]) print(ar[:4:2]) #索引到4 按2的步长 pr ...

  2. Fragment Touch事件泄露

    当Fragment的栈里面有几个fragment的时候,这个时候如果是几个fragment状态是hide,当你触摸当前fragment的时候,下层的fragment的事件被触发,这是由于Touch事件 ...

  3. Android开发——事件分发机制详解

    0. 前言   转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52566965 深入学习事件分发机制,是为了解决在Android开发中 ...

  4. html+css调用服务器端字体

    在浏览网页时,由于客户端没有安装某些特殊字体,导致网页文字无法按设计正常显示,这时我们可以使用服务器字体来避免这种现象的发送 语法 @font-face { /* 自定义字体名称 */ font-fa ...

  5. CodeForces 785C Anton and Fairy Tale 二分

    题意: 有一个谷仓容量为\(n\),谷仓第一天是满的,然后每天都发生这两件事: 往谷仓中放\(m\)个谷子,多出来的忽略掉 第\(i\)天来\(i\)只麻雀,吃掉\(i\)个谷子 求多少天后谷仓会空 ...

  6. 解决Android Studio报错:DefaultAndroidProject : Unsupported major.minor version 52.0

    解决办法是你需要将工程根目录build.gradle中的 classpath 'com.android.tools.build:gradle:2.2.0' 更改成 classpath 'com.and ...

  7. Java 基本数据类型总结一

    Java基本数据类型总结一 基本类型,或者叫做内置类型,是JAVA中不同于类的特殊类型.它们是我们编程中使用最频繁的类型.java是一种强类型语言,第一次申明变量必须说明数据类型,第一次变量赋值称为变 ...

  8. 打开Vim/Vi代码高亮

    由于新装Vim/Vi 默认是没有打开代码高亮配置的,就看到有朋友一次次到网上去找各种配置.其实Vim默认带来配置文件的样本的,只需拷贝过来就可使用. 在用户根目录(~)中新建vim的配置文件 .vim ...

  9. DOS程序员手册(十一)

    560页 版本5中新增加的子功能05h支持程序截获MS-DOS EXEC调用,并实 现自我装载.该子功能能实现内存的修补,如设置装载程序能接收的版本号 (通过SETVER设置的版本号)以及实现对装载程 ...

  10. 【ZigZag Conversion】cpp

    题目: The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows l ...