我有一个包含对象数组的类,并且有通过引用从该数组返回对象的方法。还有一种方法可以从数组中取消设置对象。
但是,如果我有一个引用数组中对象的变量,并且该元素未设置,则该变量仍然具有对它的引用。我需要在remove方法中做些什么来彻底销毁该对象,包括对它的引用。
class myClass
{
public $objectList = array();
public function __construct()
{
$objectList[] = new myObject();
}
public function &getObjectByReference()
{
return $this->objectList[0];
}
public function removeObject()
{
unset($this->objectList[0]);
}
}
$myClass = new myClass();
$referencedObject = $myClass->getObjectByReference();
// this can now use the methods from myObject
$myClass-> removeObject();
// supposed to delete the object from memory. However $referencedObject is still
// able to use all the methods from myObject.
这就是我遇到的问题,我需要能够从数组中删除并从内存中删除对象,以便引用该对象的变量不再可用。
答案 0 :(得分:0)
你有没有尝试过:
$referencedObject = &$myClass->getObjectByReference();
在放入&?
后,$ referencedObject仍然存在答案 1 :(得分:0)
要从返回值创建引用,函数必须通过引用返回(您已经这样做),并且赋值必须通过引用。所以你应该写:
$referencedObject =& $myClass->getObjectByReference();
如果你这样做,参考确实会被销毁。
但是如果你想要销毁所有具有此对象作为值的变量(以及不引用)那么这是不可能的。您只能删除实际引用,而不能删除具有相同值的变量;)
答案 2 :(得分:0)
Php正在使用垃圾收集器:如果仍然存在对该对象的引用,则该对象不会被删除。
unset($this->objectList[0])
不删除对象而是$ this-> objectList中的值,该对象仍然存在,因为他被$ referencedObject引用。
一个解决方案:当你删除对象时,告诉他他正被删除,并且在那个对象中你有一个布尔“isDeleted”。然后,对于该对象的每个方法,检查isDeleted是否为true,在这种情况下,只执行任何操作。
答案 3 :(得分:0)
这是PHP垃圾收集器的本质。要确保调用者不维护对象的引用,您必须确保它们永远不会触及原始对象。这是一个想法:
class myClass
{
public $objectList = array();
public function __construct()
{
$objectList[] = new Wrapper(new myObject());
}
public function getObject()
{
return $this->objectList[0];
}
public function removeObject()
{
$this->objectList[0]->emptyWrapper();
unset($this->objectList[0]);
}
}
class Wrapper {
private $object;
public function __construct($object) {
$this->object = $object;
}
public function __call($method, $args) {
return call_user_func_array(array($this->object, $method), $args);
}
public function __get($attr) {
return $this->object->$attr;
}
public function __set($attr, $value) {
$this->object->$attr = $value;
}
public function emptyWrapper() {
$this->object = null;
}
}
您可以使用此包装器的想法,也可以使用强制间接和句柄。我可能更喜欢使用强制间接;否则,调用者仍然可以保持包装器对象的存活 - 尽管它相当便宜。
class myClass
{
public $objectList = array();
public function __construct()
{
$objectList[] = new myObject();
}
public function getObjectHandle() {
return 0;
}
public function removeObject($h)
{
unset($this->objectList[$h]);
}
public function call($h, $method, $args) {
call_user_func(array($this->objectList[$h], $method), $args);
}
public function get($h, $attr) {
return $this->objectList[$h]->$attr;
}
public function set($h, $attr, $value) {
$this->objectList[$h]->$attr = $value;
}
}
$myClass = new myClass();
$objectHandle = $myClass->getObjectHandle();
// example method call
$myClass->call($objectHandle, 'some_method', array('arg1', 'arg2'));
$myClass->removeObject($objectHandle);