iOS Question References between Parent and initialized classes

Discussion in 'iOS Questions' started by Scott Bartgis, May 7, 2015.

  1. Scott Bartgis

    Scott Bartgis Member Licensed 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:

    Code:
    '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
    Code:
    '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?
     
  2. Erel

    Erel Administrator Staff Member Licensed User

    You cannot access the fields of another module without knowing the module type.

    However you can access subs with CallSub methods.
     
  3. Scott Bartgis

    Scott Bartgis Member Licensed 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?
     
  4. narek adonts

    narek adonts Well-Known Member Licensed User

    If I understood your question correctly you will ref the variable as public you can access it as modulename.variablename.
     
  5. Scott Bartgis

    Scott Bartgis Member Licensed 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?
     
  6. narek adonts

    narek adonts Well-Known Member Licensed User

    why you are not just using PersonManagement.myUserID ?
     
  7. narek adonts

    narek adonts Well-Known Member Licensed User

    Code:
    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
     
  8. Scott Bartgis

    Scott Bartgis Member Licensed 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.
     
  9. narek adonts

    narek adonts Well-Known Member Licensed User

    I think you should just use CallSub for this case. Thats all
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice