sharing data between viewControllers

Discussion in 'iOS Programming' started by flummoxed, Jan 1, 2011.

  1. flummoxed macrumors member

    Joined:
    Nov 27, 2010
    #1
    I have 2 viewControllers that are part of a navigationController setup.

    If I am in viewController A and push to viewCntrl B, how can I set a label text in B to match a label in A? Its a dynamic label not a constant value.

    Also, if I make a change to the label text in B I need to update the label in A and also update an int ivar in A to match the new values, so that when I pop back to A the values are current.
     
  2. Matthew Yohe macrumors 68020

    Joined:
    Oct 12, 2006
    #2
    Understand how model view controller works is a good start.

    Basically, both of your view controllers can hold a reference to some data model and when you push on a controller, you should also give it a pointer to your data. Then when you change it in your controller, it will change in your data source.

    Very simple and crude example, but if you don't get it, you should really read some more on apple's dev site.
     
  3. flummoxed thread starter macrumors member

    Joined:
    Nov 27, 2010
    #3
    Well I have read the Apple docs and watched several lectures on MVC, but I guess it hasn't fully sunk in yet.

    I guess the problem is in the fact that my app started out as a single viewController which served as its own data model, and the data existed in its ivars. That was the simplest way to get started and just get the program working. I knew eventually that I would have to separate the data as an explicit model object. Then I started creating more viewControllers, and now they have to share the same data.

    My confusion is about exactly where the data model exists in the running program. If I create a new class object with ivars as the data, then that object has to be instantiated at some point in the program for the data to exist.

    I can't instantiate it in any of the viewControllers since any of them may disappear at some point in the program and my data along with it.

    Would it be proper to instantiate the data model in the AppDelegate?
    That way the data model lives for the life of the entire app.

    Do I make the data model an instance variable of the AppDelegate or just allocate an instance in the -applicationDidFinishLaunching method , and then initialize the data by calling the init method of the data model?
    When the app quits then I could just release it in the AppDelegate's dealloc method. ?
     
  4. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #4
    False. Any view controller using the model object should have an ownership claim on the object. That is, the controller should retain the model for as long as it needs it, and release it when it no longer needs it. As long as at least one controller has ownership, the object will continue to exist.

    Most programs will always have at least one controller.


    That's one way to do it. There is no single answer that's "proper" in all situation. You have to know enough about your design to know when and where to create model objects (plural because some things are better modeled by multiple objects), and when and where it's appropriate to let them die. This implies that you have a design, rather than a bunch of cobbled-together controllers trying to communicate with one another.

    Now might be a good time to step back from the hacking coding and work out a suitable Model design. Resist the temptation to continue hacking or doing makeshift code. You're really only going to learn about model objects by doing it (and failing at it, then fixing the failure, then redesigning for an unforeseen shortcoming, then failing, fixing, etc.).

    The goal is to make a design that works the same as what you have now, but has an actual model object (or objects). Since you have code that works now (presumably), you can do an A/B test to confirm that the evolving yet still buggy model-based code works the same as the one you have now. As long as there are any differences in behavior, you haven't successfully completed the transition to the model-based code. If you have unit tests, or really any kind of tests, even manual ones, then this is the time to use them to confirm behavioral identicality between two versions of the program. If you don't have any tests or specs or written down description of behavior, now might be a good time to do that, before starting a major rework of factoring out an actual model object.


    The entire program's memory, which includes all objects, will be discarded when the app quits. It's not necessary to release something whose lifetime is the entire program.
     
  5. flummoxed thread starter macrumors member

    Joined:
    Nov 27, 2010
    #5
    Thanks for the detailed reply.

    If that is the case, then why does Apple release the main app window at the end of the appDelgate dealloc method?
    Code:
    - (void)dealloc {
        
        [window release];
        [super dealloc];
    }
    
     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    Please provide the URL where that is shown.

    If you want a counter-example, that is, an app delegate written by Apple whose dealloc doesn't do that, try any of these:
    http://developer.apple.com/library/...le/Listings/Ancillary_Code_AppDelegate_m.html
    http://developer.apple.com/library/...ns/Listings/Ancillary_Code_AppDelegate_m.html
    http://developer.apple.com/library/ios/#samplecode/TopSongs/Listings/Application_AppDelegate_h.html

    You can find more examples (both with and without dealloc's) by googling this:
    ios app delegate site:developer.apple.com


    Without seeing any other context, my first guess for why there'd be a dealloc in an app delegate class is simple consistency.

    My second guess is that there can be more than one app delegate over the lifetime of an application. The delegate can be changed at any time, for any reason that is consistent with the logic and design of the app. In that case, one would want the now-unused delegate to behave properly.

    An app delegate doesn't even have to be a view controller, if you were specifically wondering about the release of the window.
     
  7. flummoxed thread starter macrumors member

    Joined:
    Nov 27, 2010
    #7
    Its just how it comes out from the View Based Application template provided by Apple in Xcode.

    In this case the AppDelegate is an NSObject.

    No biggie. I just figured if Apple releases the objects in the dealloc there must be a reason.
     
  8. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #8
    In that case the answer is simple: a template has no way to predict how the delegate class will be used, nor what it's lifetime will be. Since there's no harm in having a -dealloc for something that lives through the entire program, but there is harm for the opposite (no -dealloc for something that doesn't live the entire program), Apple chose the more harmless one.

    A -dealloc for something that lives the entire program is simply never called. It's mostly harmless.
     
  9. flummoxed thread starter macrumors member

    Joined:
    Nov 27, 2010
    #9
    Well, back to the original problem...

    I have tried every variation I can think of for how to implement this model object and I still can't get the other viewControllers to "see" it.

    I assumed that by allocating an instance in the appDelegate when the app loads that would allow it to be visible, but it only has file scope.
    I have included the model.h file in both viewControllers and declared the object variable name that I used to allocate the object, but they don't know about it.

    Where do you allocate the instance of model.number
    so that both controller A and controller B can access and set its value,
    and have the same value reflected when switching back and forth between the controllers?
     
  10. chown33 macrumors 604

    Joined:
    Aug 9, 2009
  11. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #11
    One way to do this is to store the string in NSUserDefaults and post a notification whenever it changes. A new view controller will read the value when in viewDidLoad and will register for the notification. If it receives the notification it updates the label.

    Using notifications provides less coupling between the various view controllers that need access to this variable.
     
  12. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #12
    Assuming is a bad way to program. Either you're sure of something or you use trial-and-error to verify your propositions.

    You seem to lack an inherent understanding of the object-oriented-programming concepts of encapsulation and variable scope. I'd suggest stepping back from the real coding and (re)visiting all the fundamentals until you understand them.
     
  13. flummoxed thread starter macrumors member

    Joined:
    Nov 27, 2010
    #13
    Sorry to bother you.

    Everybody that has posted a question has a lack of understanding about something. I "assumed" the purpose of this forum was to answer people's questions, not heap criticism upon them for not being a Demi-god.
     
  14. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #14
    Oh, you're not bothering me. I thought I would just try to provide what I thought was some helpful advice, along the lines of "walk before you run." My apologies if you felt it was otherwise.

    Granted. But when you seem to lack an understanding of the fundamentals, making assumptions about how things should work show that you may be in over your head.

    It is, in a way, at least to me. I don't like to just give people direct answers to questions but rather I prefer to guide them to their own discovery.

    I never even mentioned Demi-God. What does that have to do with anything?
     

Share This Page