LittleBai117 2017-07-21 15:10:22 2216次浏览 3条回复 0 0 0

yii2源码中,个人感觉有一处可以改良的地方,在yii\base\event中的事件定义中,解除事件绑定的函数off()定义源码如下:

public static function off($class, $name, $handler = null)
{
        $class = ltrim($class, '\\');
        if (empty(self::$_events[$name][$class])) {
            return false;
        }
        if ($handler === null) {
            unset(self::$_events[$name][$class]);
            return true;
        }

        $removed = false;
        foreach (self::$_events[$name][$class] as $i => $event) {
            if ($event[0] === $handler) {
                unset(self::$_events[$name][$class][$i]);
                $removed = true;
            }
        }
        if ($removed) {
            self::$_events[$name][$class] = array_values(self::$_events[$name][$class]);
        }
        return $removed;
    }

显然在$handler !== null的情况下,函数首先会删除对应的self::$_events[$name][$class]数组的变量,由于采用unset() 函数删除,不会改变数组索引值。作者又在最后通过 array_value()函数处理下。 然后这些直接可以使用array_splice()完成。个人觉得这样会更加的高效,大家有什么意见呢? 改完的代码如下:

public static function off($class, $name, $handler = null)
{
        $class = ltrim($class, '\\');
        if(empty(self::$_events[$name][$class])){
            return false;
        }
        if ($handler === null){
            unset(self::$_events[$name][$class]);
            return true;
        }
        foreach (self::$_events[$name][$class] as $i => $event){
            if($event[0] === $handler){
                array_splice(self::$_events[$name][$class], $i, 1);
                return true;
            }
        }
        return false;
}
  • 回复于 2017-07-26 17:32 举报

    挺不错的,但是$removed是不能去掉的,否则只等于一次,直接就return true了,而原代码可能会删除好多个。而且多次array_splice会比array_values高吗?并不一定吧。

     foreach (self::$_events[$name][$class] as $i => $event){
                if($event[0] === $handler){
                    array_splice(self::$_events[$name][$class], $i, 1);
                    return true;//直接就跳出了
                }
            }
            return false;
    
    1 条回复
    回复于 2017-07-28 13:31 回复

    确实,$removed是不能去掉的。如果考虑会有删除多个绑定事件的情况,那我觉得还是源码比较高效,最后进行一次排序。而我改的,是在每次删除后都排序,性能应该差点。(最近在忙公司的项目,没有继续看源码,后续会再深挖下这块的源码)
    谢谢,您的互动,学习到了。

    觉得很赞
  • 回复于 2018-03-02 17:02 举报

    继续学习,才

    觉得很赞
  • 回复于 2018-03-02 17:08 举报

    fdsafds

您需要登录后才可以回复。登录 | 立即注册