• 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 就是将 一个 事件 从上往下 依次传递,直到找到对应的 相应方法的类 为止。
  • 相关阅读:
    二.二分法总结
    20201214 Json与pickle数据序列化
    20201213-1 HTML基本标签(一)
    20201207-2 openpyxl 库与模块导入
    20201207-1 实例变量与类变量
    20201205-3 HTML环境搭建与文件基本结构
    20201205-2 HTML概念与版本
    20201204-3 opp编程好处与构造函数
    20201204-2 面向对象特性介绍
    20201204-1 面向对象介绍
  • 原文地址:https://www.cnblogs.com/xuejinhui/p/4253295.html
Copyright © 2020-2023  润新知