将Loader.active设置为false不会立即释放项目 [英] Setting Loader.active to false doesn't release item immediately

查看:121
本文介绍了将Loader.active设置为false不会立即释放项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用例,其中会根据是否存在属性值来创建或删除引用该属性值的对象.我为此目的使用Loader,其中active属性绑定到该属性,也就是说,当该属性具有非null值时,加载程序被激活,当其设置为null时,它被停用. /p>

但是问题是,加载程序不会立即释放其项目,因此有一段时间该项目引用了null属性,因此无法访问数据,而将该属性设置为null会触发重新评估,从而导致重新赋值cannot read property x of null群.

简单的逻辑表明不应发生这种情况.因此,我认为可能是绑定评估的顺序错误,导致在取消加载程序之前评估了项目的绑定.因此,我尝试删除active的绑定并手动进行设置.但是问题仍然存在.

因此,这里有一个最小的表示方式来说明正在发生的事情:

Window {
  id: main
  visible: true
  width: 500
  height: 300

  property QtObject object : QtObject {
    property QtObject subObject: null
  }

  QtObject {
    id: subo
    property int i : 1
  }

  Loader {
    id: ld
    active: false
    sourceComponent: Text {
      text: object.subObject.i
      font.pointSize: 20
    }
  }

  MouseArea {
    anchors.fill: parent
    onClicked: {
      if (object.subObject) {
        ld.active = false
        object.subObject = null
      } else {
        object.subObject = subo
        ld.active = true
      }
    }
  }
}

请注意,在这种情况下,之前将显式停用加载程序,将属性设置为null,但是,每次发生这种情况时,控制台中都会出现类型错误:

qrc:/main.qml:25: TypeError: Cannot read property 'i' of null

这似乎不是正确的行为.那么也许是个错误?还是我错过了什么?关于如何解决该限制的任何建议?请注意,在使用视图或转发器时可以避免这种情况.

更新:为进一步说明,在我的实际生产代码中,如果不引用该属性,加载程序的项目就无法真正存在.因此,想法是仅应在属性具有null以外的值时创建对象,而在null时将其销毁.

解决方案

我昨天遇到了这个问题.我需要两个共享相同属性的加载器.在C ++类中,我一个接一个地更新了两个Loader的active属性,这也将导致该问题.我对此的解决方案是使用Binding并进行如下设置:

Binding {
        target: contentItemAlias
        property: 'currentIndex'
        value: if (header.status == Loader.Ready) 
        header.item.currentIndex //ensure the current status is not null
        when: content.status === Loader.Ready // the content is ready
    }

实际上,这可能对您没有帮助,但这是我的代码中的解决方案.希望您能看到它并尝试使用binding.祝你成功. 这是我的项目的链接: https://github.com/begoat/qmlLive

I have a use case where depending on the presence or absence of a property value an object referencing it is either created or removed. I am using a Loader for the purpose, where the active property is bound to the property, that is when the property has a non-null value the loader is activated, when it is set to null it is deactivated.

However the problem is that the loader doesn't release its item immediately, so for a moment the item references a null property, thus is unable to access data, while the setting of the property to null triggers reevaluations that result in a swarm of cannot read property x of null.

Simple logic suggest this should not happen. So I thought that maybe the problem is the order of binding evaluations is wrong, resulting in the item's bindings being evaluated before the loader is deactivated. So I tried removing the binding for active and setting it up manually. The problem however persisted.

So here is a minimal representation to illustrate what's going on:

Window {
  id: main
  visible: true
  width: 500
  height: 300

  property QtObject object : QtObject {
    property QtObject subObject: null
  }

  QtObject {
    id: subo
    property int i : 1
  }

  Loader {
    id: ld
    active: false
    sourceComponent: Text {
      text: object.subObject.i
      font.pointSize: 20
    }
  }

  MouseArea {
    anchors.fill: parent
    onClicked: {
      if (object.subObject) {
        ld.active = false
        object.subObject = null
      } else {
        object.subObject = subo
        ld.active = true
      }
    }
  }
}

Note that in this case the loader is explicitly deactivated before the property is set to null, yet nonetheless, every time that this happens I get a type error in the console:

qrc:/main.qml:25: TypeError: Cannot read property 'i' of null

This doesn't seem like correct behavior. So maybe a bug? Or am I missing something? Any suggestions on how to work around that limitation? Note that this is somehow avoided when using views or repeaters.

Update: To clarify further, in my actual production code the loader's item cannot really exist without referencing that property. So the idea was that the object should only be created when the property has a value other than null and be destroyed when it is null.

解决方案

I came across this yesterday. I need two Loaders which share the same property. In C++ class, I update the two Loader's active property one by one, which will also lead to that problem. My solution for this is using a Binding and do some setting like this:

Binding {
        target: contentItemAlias
        property: 'currentIndex'
        value: if (header.status == Loader.Ready) 
        header.item.currentIndex //ensure the current status is not null
        when: content.status === Loader.Ready // the content is ready
    }

Actually maybe this will not help you, but this is the solution in my code. I hope you will see it and have a try at binding. Wish you success. here is the link to my project: https://github.com/begoat/qmlLive

这篇关于将Loader.active设置为false不会立即释放项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆