需要动态地将方法附加到类。
我的代码:
func imageViewTapped(recognizer:UITapGestureRecognizer) {
guard let imageView = recognizer.view as? UIImageView
else { return }
imageView.tintColor = UIColor.orangeColor()
}
问题:为什么<?php
class stdClass1 {
public function __call($method, $arguments) {
return call_user_func_array(Closure::bind($this->$method, $this, get_called_class()), $arguments);
}
}
class stdClass2 {
function stdRunMethod() {
$obj = new stdClass1();
$obj->test = function() {
echo 'a simple function';
};
$obj->test();
$obj2 = new stdClass1();
$obj2->test();
}
}
$obj = new stdClass2();
$obj->stdRunMethod();
方法仅针对test
类的第一个实例运行?如何为所有新实例附加此方法?
答案 0 :(得分:2)
改为尝试(demo):
<?php
class stdClass1 extends \stdClass
{
private static $addedClosures = array();
public function __set($name, $value)
{
if ($value instanceof \Closure) {
self::$addedClosures[$name] = $value;
}
else {
parent::__set($name, $value);
}
}
public function __call($method, $arguments)
{
if (isset(self::$addedClosures[$method]))
return call_user_func_array(self::$addedClosures[$method], $arguments);
return call_user_func_array($method, $arguments);
}
}
class stdClass2 extends \stdClass
{
function stdRunMethod()
{
$obj = new stdClass1();
$obj->test = function () {
print_r('a simple function');
};
$obj->test();
$obj2 = new stdClass1();
$obj2->test();
}
}
答案 1 :(得分:1)
它只运行一次的原因是stdClass1
的每个副本都维护着自己的一组变量。在下面的
$obj1 = new stdClass1();
$obj1->a = '1';
$obj2 = new stdClass1();
$obj2->a = '2';
echo $obj1->a;
您将获得值1
作为输出。因为在大多数情况下他们保持不同的参考除非您使用static
关键字。静态属性在类的所有实例之间共享,应该谨慎使用,但这是您正在考虑的内容。您正在考虑的事情可以像这样做
<?php
class stdClass1 {
private static $methods = [];
public function __call($method, $arguments) {
return call_user_func_array(Closure::bind($this->methods[$method], $this, get_called_class()), $arguments);
}
public function __set($name, $value) {
if (is_callable($value)) {
$this->methods[$name] = $value;
} else {
parent::__set($name, $value);
}
}
}
我们在这里使用静态的已定义属性来保存所有动态方法,并且我们正在使用魔术__set
属性将方法设置为数组。
话虽如此,动态地将方法加载到对象中是不好的。不要这样做