bb.donnay-software.com

Donnay Software Web Forums
It is currently Sun Nov 17, 2019 5:56 pm

All times are UTC - 7 hours




Post new topic Reply to topic  [ 2 posts ] 
Author Message
PostPosted: Thu Sep 12, 2019 2:55 pm 
Offline
User avatar

Joined: Thu Feb 11, 2010 1:39 pm
Posts: 472
Hi All

How can the numerous dynamic class instances created by DC_DbRecord():new() be removed from memory when the function terminates. Alaska made it clear in their documentation that Dynamically created objects must be explicitly destroyed by executing Classdestroy(oRecord) function otherwise they will remain in memory

Thanks

Joe

Code:
/*
This sample program shows how to browse an array of objects
using the OBJECTVAR clause of DCBROWSECOL.
*/

#include "dcdialog.ch"
#INCLUDE "appevent.CH"

FUNCTION Main()

LOCAL oData, aData1[0], aData2[0], GetList[0], oBrowse1, oBrowse2, ;
      GetOptions, oRecord, i, nRecNo, lStatus, nPointer := 1

DC_LoadRdds()

USE ..\..\data\customer VIA 'FOXCDX'

oRecord := CUSTOMER->(DC_DbRecord():new())

DO WHILE !CUSTOMER->(Eof())
  oRecord := CUSTOMER->(DC_DbRecord():new())
  CUSTOMER->(DC_DbScatter(oRecord))
  AAdd(aData1,{oRecord,CUSTOMER->(RecNo())})
  AAdd(aData2,oRecord)
  CUSTOMER->(dbSkip())
ENDDO

wtf aData1, aData2


// Browsing a multi-dimensional array with objects
@ 0,0 DCSAY 'This is a \i\ubrowse\c of a \bmulti-dimensional\c array of objects:\n' FORMATTED ;
      SAYSIZE 0 FONT '10.Lucida Console' ;
      RESIZE DCGUI_RESIZE_REPOSONLY_Y

@ 1,0 DCBROWSE oBrowse1 DATA aData1 SIZE 20,10 FIT ;
      FILTER {|a|Left(a[1]:bill_city,1)$'ASWBGH'} ;
      POINTER nPointer ;
      RESIZE DCGUI_RESIZE_RESIZEONLY ;
      ;// EDIT xbeBRW_ItemSelected ;
      ITEMSELECTED {||EditRecord(aData1[nPointer,1]),oBrowse1:refreshCurrent()}

DCBROWSECOL OBJECTVAR cust_nmbr ELEMENT 1  HEADER 'ID'       WIDTH  5 PARENT oBrowse1
DCBROWSECOL OBJECTVAR bill_name ELEMENT 1  HEADER 'Name'     WIDTH 15 PARENT oBrowse1
DCBROWSECOL OBJECTVAR bill_strt ELEMENT 1  HEADER 'Address'  WIDTH 15 PARENT oBrowse1
DCBROWSECOL OBJECTVAR bill_city ELEMENT 1  HEADER 'City'     WIDTH 10 PARENT oBrowse1
DCBROWSECOL OBJECTVAR bill_zip  ELEMENT 1  HEADER 'Zip'      WIDTH  4 PARENT oBrowse1
DCBROWSECOL ELEMENT 2 HEADER 'Record' WIDTH 3 PICTURE '999' PARENT oBrowse1

// Browsing a single-dimensional array with objects
@ 12,0 DCSAY 'This is a \i\ubrowse\c of a \bsingle-dimensional\c array of objects:\n' FORMATTED ;
   SAYSIZE 0 FONT '10.Lucida Console'

@ 13,0 DCBROWSE oBrowse2 DATA aData2 SIZE 20,10 FIT ;
       RESIZE DCGUI_RESIZE_RESIZEONLY_X

DCBROWSECOL OBJECTVAR cust_nmbr HEADER 'ID'       WIDTH  5 PARENT oBrowse2
DCBROWSECOL OBJECTVAR bill_name HEADER 'Name'     WIDTH 15 PARENT oBrowse2
DCBROWSECOL OBJECTVAR {|o|Upper(Trim(o:bill_strt))} HEADER 'Address'  WIDTH 15 PARENT oBrowse2
DCBROWSECOL OBJECTVAR {|o|Trim(o:bill_city)} HEADER 'City'     WIDTH 10 PARENT oBrowse2
DCBROWSECOL OBJECTVAR bill_zip  HEADER 'Zip'      WIDTH  4 PARENT oBrowse2

@ 24,0 DCPUSHBUTTON CAPTION 'Browse Objects in GetList' SIZE 20 ;
       ACTION {||BrowseGetListObjects(GetList)}

DCGETOPTIONS RESIZE

DCREAD GUI FIT ADDBUTTONS TITLE 'Browse array of objects' TO lStatus ;
   SETAPPWINDOW OPTIONS GetOptions

IF lStatus
  FOR i := 1 TO Len(aData1)
    oRecord := aData1[i,1]
    nRecno := aData1[i,2]
    CUSTOMER->(dbGoTo(nRecno))
    CUSTOMER->(DC_DbGather(oRecord))
  NEXT
ENDIF

RETURN nil

PROC appsys; return

* -----------

STATIC FUNCTION BrowseGetListObjects( aGetList )

LOCAL GetList[0], oBrowse

@ 0,0 DCBROWSE oBrowse DATA aGetList SIZE 20,20 FIT

DCBROWSECOL DATA {||oBrowse:arrayElement} HEADER 'Nmbr' WIDTH 3 PICTURE '9999' PARENT oBrowse

DCBROWSECOL DATA {||DC_GetListType(aGetList[oBrowse:arrayElement,nGETLIST_TYPE])} ;
   HEADER 'Type' WIDTH 15 PARENT oBrowse

DCBROWSECOL DATA {||aGetList[oBrowse:arrayElement,cGETLIST_CAPTION]} ;
   HEADER 'Caption' WIDTH 15 PARENT oBrowse

DCBROWSECOL OBJECTVAR className() ELEMENT oGETLIST_OBJECT ;
   HEADER 'Class Name' WIDTH 10 PARENT oBrowse

DCBROWSECOL OBJECTVAR setParent() ELEMENT oGETLIST_OBJECT ;
   HEADER 'Parent' WIDTH 10 PARENT oBrowse

DCBROWSECOL OBJECTVAR currentSize()[1] ELEMENT oGETLIST_OBJECT ;
   HEADER 'Width' WIDTH 3 PARENT oBrowse PICTURE '9999'

DCBROWSECOL OBJECTVAR currentSize()[2] ELEMENT oGETLIST_OBJECT ;
   HEADER 'Height' WIDTH 3 PARENT oBrowse PICTURE '9999'

DCBROWSECOL OBJECTVAR currentPos()[1] ELEMENT oGETLIST_OBJECT ;
   HEADER 'Col' WIDTH 3 PARENT oBrowse PICTURE '9999'

DCBROWSECOL OBJECTVAR currentPos()[2] ELEMENT oGETLIST_OBJECT ;
   HEADER 'Row' WIDTH 3 PARENT oBrowse PICTURE '9999'

DCBROWSECOL OBJECTVAR setFontCompoundName() ELEMENT oGETLIST_OBJECT ;
   HEADER 'Font' WIDTH 15 PARENT oBrowse



DCREAD GUI FIT TITLE 'Browsing GetList' MODAL

RETURN nil

* ------------

FUNCTION EditRecord( oRecord )

LOCAL getList[0]

@ 0,0 DCSAY 'Billing Name' GET oRecord:bill_name
@ 1,0 DCSAY 'Billing Street' GET oRecord:bill_strt

DCREAD GUI FIT TITLE 'Editing Data' ADDBUTTONS ENTEREXIT TO lStatus

IF lStatus
  CUSTOMER->(DC_DbGather(oRecord))
ENDIF

RETURN nil



Top
 Profile  
 
PostPosted: Thu Sep 12, 2019 3:32 pm 
Offline
Site Admin
User avatar

Joined: Wed Jan 27, 2010 6:58 pm
Posts: 4002
Location: Boise, Idaho USA
This is true. All classes in Xbase++ are dynamically created, but those created by ClassCreate() can be destroyed.

If you intend to use the same alias name for different databases, then you should ClassDestroy() on the class created by DC_DbRecord() before calling DC_DbRecord() again with a different data structure but the same alias. This is true even if you have databases opened in different threads, because dynamically created classes are not thread-safe.

You can pass the name of the class to be created and give it any name you want, but by default it will be DATA_ + Alias().

It is not problematic to fail to destroy a class created by DC_DbRecord(). It really is not necessary. In fact, it is best that the class NOT be destroyed because DC_DbRecord() will likely be used with the same database later in the program. If the class already exists, it will not be created. You could write a wrapper function that calls DC_DbRecord() and saves away the record object onto a stack (an array), end then call a function that destroys all the classes when closing the databases.

_________________
The eXpress train is coming - and it has more cars.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group