BeeFramework 笔记 四(UISignal 总结)

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 就是将 一个 事件 从上往下 依次传递,直到找到对应的 相应方法的类 为止。
原文地址:https://www.cnblogs.com/xuejinhui/p/4253295.html