1

我在脚本的开头定义了一个线程派生类:

    class procthread : thread
    { 
......      

        object init( object self)   
        {   
...
        }   

        void RunThread( object self )   
        {     
.....    
        }

    }

然后是 MyDialog 类,它应该使用这个线程:

Class MyDialog: UIFrame

{
object wrkthread
.....
    TagGroup CreateMyDialog(Object self, number nref)
    {
........
        btn0=DLGCreatePushButton("+","DoBut0").DLGIdentifier("#PushB0")
        wrkthread=alloc(procthread) ////<----- works

        return DialogTG
    }


    Object Init(Object self, number nref) return self.super.Init(self.CreateMyDialog(nref))

    Void DoBut0(Object self) 
        {
        wrkthread=alloc(procthread) ////<---- does not work
        } 
}

根据脚本的逻辑,每次按下按钮时都应该分配和激活线程。然而,在 on_button_pressed 处理程序中调用的“wrkthread=alloc(procthread)”会引发异常“找不到类 'procthread'”。同时,来自 Init 函数的相同调用运行良好并且线程运行。

这里有什么问题?我不敢相信类定义仅在主线程中可见,这没有任何意义。

如果我犯了错误,你能纠正吗?如果这是一个功能 - 如何绕过它?

4

1 回答 1

1

问题是,UI 操作(如果您想到的话,也必须)在 DM-Application 主线程上运行。因此,DoBut0 操作作用于与脚本中不同的线程。所以在某种程度上,是的,启动脚本解释器只将脚本代码保留在“它的”范围内,并且单独创建的线程(如 UI 操作)不知道它。

解决它的一种方法是让您的类保留要从按钮执行的类的成员对象,从而强制它保持在范围内。(这是您上面的“工作”解决方案。)如果您需要每个 UI 操作都有一个“新”对象,您可以通过克隆对象而不是在成员函数中分配它来实现这一点。(即成员对象只是一个“模板”对象)

这是另一个例子:

Class AClass
{
    AClass(Object self)     Result("\n object AClass created: ID=" + self.ScriptObjectGetID() )     // Just for debugging info 
    ~AClass(Object self)    Result("\n object AClass destroyed: ID=" + self.ScriptObjectGetID())    // Just for debugging info . Check no memory leak!!

    void AAction(Object self) Result("\t ACTION A")
}

Class BClass : UIFrame
{
    BClass(Object self)     Result("\n object BClass created: ID=" + self.ScriptObjectGetID() )     // Just for debugging info 
    ~BClass(Object self)    Result("\n object BClass destroyed: ID=" + self.ScriptObjectGetID())    // Just for debugging info . Check no memory leak!!

    Object keepOtherOBJ

    void CreateOtherObject(Object self) 
    {
        result("\nAllocation prepare")
        keepOtherOBJ = Alloc(AClass)
        result("\nAllocation done")
    }

    void CallOtherAction(Object self) 
    {
        Result("\n Calling other action:")
        keepOtherOBJ.AAction()
    }

    void ButtonAction(Object self)
    {
        Result("\n Pressing button")
        //  self.CreateOtherObject()                // ==> THIS IS NOT working. Button action is called separately in memory which doesn't know about "Class A"
        self.CallOtherAction()


        // Or you may want to clone the "template" and run it like this
        keepOtherObj.Clone().AAction()
    }

    Object InitAndShow(Object self)
    {

        TagGroup DLGtg,DLGitems
        DLGtg = DLGCreateDialog("Test",DLGitems)
        DLGitems.DLGAddElement( DLGCreatePushButton("Other Class Action","ButtonAction") )
        self.Init(DLGtg)

        self.CreateOtherObject()                // ==> THIS IS working. The object is created and kept as local member

        self.Display("Test")
    }
}

// MAIN script
{
    Object BObject = Alloc(BClass)
    BObject.InitAndShow()   
}
于 2017-03-24T17:39:23.987 回答