iOS Question References between Parent and initialized classes

Scott Bartgis

Member
Licensed User
Longtime User
I have seen many discussions in the B4A forum, but nothing seemed to match what I am curious to know. To make reusable code, I like to use Class objects for a lot of things. In one of my apps, the Class is initialized including a reference to the Parent.

This is a crude mock up skeleton of the question's code:

B4X:
'Main
Sub Process_Globals
    Public App As Application
    Public NavControl As NavigationController
    Public MainPage As Page
    Public myObject As SomeObject
    Public myUserID As Int : myUserId = 1123
End Sub

Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    NavControl.ToolBarVisible = False
    NavControl.NavigationBarVisible = False
    SomeObject.Initialize(Me, "John", "Doe")
End Sub

Sub CompletedAction
    Log("Action complete")
End Sub

B4X:
'Class MyObject
Sub Class_Globals
    ParentModule As Object
    FirstName, LastName As String
    CreatedBy As Int
End Sub

Sub Initialize(mParentModule As Object, mFirstName As String, mLastName As String)
    ParentModule = mParentModule
    FirstName = mFirstName
    LastName = mLastName
    CreatedBy = ParentModule.myUserID   '<<<< does not work
    ParentModule.ActionComplete '<<<< does not work

    CallSub(ParentModule, "ActionComplete") '<<<< this works
End Sub

End Class

Things I have thought of:

1) Pass the myUserID as a param in every Sub in the MyObject class

2) Create a UserID in MyObject and set it once during Initialize so all Subs can get it.

#2 seems like the obvious choice, but what if the value was something dynamic? Like, something the user has picked from a list. I would want the value from the Main at the moment of the Class Sub, not the original value passed during Initialize.

So now the question: Can an initialized object get to any of the public vars in the parent?
 

Scott Bartgis

Member
Licensed User
Longtime User
I understand. Let's say I know the module type being referenced. If it is B4i it will be a Code Module. If B4A it is an Activity.

Can I get to those values if I know which type of module I am trying to get to?
 
Upvote 0

Scott Bartgis

Member
Licensed User
Longtime User
Yes, that is true. In the example Main.myUserID would give the correct answer, but the Class is not always initialized by Main. Let's say it is PersonManagement who wants to use the MyObject. Now, MyObject is talking to Main.myUserID, but it should be talking to PersonManagement.myUserID. But the only thing MyObject knows is ParentModule.

The question, modified after Erel's statement about knowing the module type is: Can a class reference its parent's variables when the parent type is known and you have a reference to the parent object?
 
Upvote 0

narek adonts

Well-Known Member
Licensed User
Longtime User
B4X:
Sub Class_Globals
    ParentModule As Object
    FirstName, LastName As String
    CreatedBy As Int
End Sub

Sub Initialize(mParentModule As Object, mFirstName As String, mLastName As String)
    ParentModule = mParentModule
    FirstName = mFirstName
    LastName = mLastName
    CreatedBy = ParentModule.myUserID   '<<<< does not work
   ' this line will work if when creating the module with IDE you will name the module ParentModule
   ParentModule.ActionComplete '<<<< does not work
 ' this line will work if when creating the module with IDE you will name the module ParentModule
  
  CallSub(ParentModule, "ActionComplete") '<<<< this works
End Sub

End Class
 
Upvote 0

Scott Bartgis

Member
Licensed User
Longtime User
That is true, but not what I am trying to do. MyObject will be used by many different modules. It won't always be Main, or PersonManagement. I don't want a module named ParentModule. ParentModule is a reference back to the module who created the MyObject.

Here is the real example of what I would like to do (just want to know if I have to do it some other way). This is how it was done in VisualBasic.Net - which I know has more power.

The app controls a device with 4 different targets to control. Let's call them "zones". Zone 1, 2, 3, and 4 are independent of each other, but contained on the same device. The UI can control only one zone at a time, but the user can select which zone he is controlling. We call that the CurrentZone, or FocusedZone. It is an Int from 1 to 4.

Main starts and queries an IP address to obtain information about the target device. Once it knows which device it is talking to, it loads the appropriate UI module. This can be UI_For_Device_X, UI_For_Device_Y, UI_For_Device_Z. UI has a Public CurrentZone As Int defaulted to 1. There will only be one of those UI_xxxxx modules loaded.

The UI module creates an object for the Device it is controlling. Why the UI and not Main you would ask since Main is always present? The UI module contains the logic specific to each device to retrieve different information via different queries. I saw a serious code management mess if Main contained all of the logic for each specific device when the real difference came from the UI rendering side. Main's job is to find the device and load the correct UI module.

Device is an object created by UI_For_Device_X. Device is told its parent module is UI_For_Device_X. The Device object has a List of ZoneObjects from 0 to 4 representing the Zones the UI can control. Zone 0 is not used by the user, so it is not important for this - also it makes the List indexes match the visible zone #. ZoneObjects know how to do specific commands for their zone.

So here is the meat of the question... UI_For_Device_X has CurrentZone=2 and User presses button "Pause".

What I "want" to do from UI_For_Device_X is Device.Pause. Device will look at its ParentModule, get the CurrentZone, and send it to its ZonePlayers.Get(2) and then call Pause inside of the specific ZonePlayer.


I guess what I need to do is UI_For_Device_X should get his own reference to Device.ZonePlayers.Get(2) and then call Pause there.
 
Upvote 0
Top