Subclassing

Discussion in 'iOS Programming' started by larswik, Sep 8, 2011.

  1. larswik macrumors 68000

    Joined:
    Sep 8, 2006
    #1
    I have 3 UIViewController for 3 different XIB windows that gets pushed in by the navigationController. There is a button on the second page that when pressed pushes the 3rd pushViewController. When that button is pressed it also goes to a website and downloads a list of names to populate an UITableView.

    My Question: When the program launches that would be the ideal time to load the names from the server and store as strings in an NSArray, not when the button is pressed on the second page. How would the secondViewController access the information on the firstViewController Instance variables?

    If secondViewController was a subclass of firstViewController I could gain access to that instance variable values, correct? Then the firstViewController would be subclassed from UIViewController. This way all of my viewControllers first, second and third would inhearit from UIViewController?

    This would link all of the controllers together and I could use any instance variables from each super class which I could get information from that variables?

    Is my thinking there right?
     
  2. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #2
    Incorrect. Since secondViewController and firstViewController are separate instances, they each have their own sets of instance variables. That's why they are called 'instance' variables.

    If you want secondViewController to have access to firstViewController's instance variables, you would need to give secondViewController access to the firstViewController instance.
     
  3. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #3
    I see. To give it access to my instance variables in FirstViewController I would then need to #import my firstViewController in my secondViewController.h.
     
  4. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #4
    That's step 1. Step 2 is you'd need to give your secondViewController an actual instance of FirstViewController (or firstViewController, or whatever the real class is).

    Importing the @interface of a class simply tells the importing code what the structure of the imported class is. That is, it tells the importer what the names of the instance variables are, what the methods are, etc. It doesn't actually create an instance anywhere.

    Remember, a class is just a factory for creating instances that have the same characteristics (same instance variable names, same methods). You don't make a milkshake by putting a cow into a blender. The cow makes milk, which is what goes into the blender. The cow is a milk factory. A cow is also a calf factory, but the calf instances can be male or female, so not every instance produced is another milk factory. And if you want to make chevre or pecorino, you need a completely different factory (goat or sheep).
     
  5. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #5
    Thanks Chown33, I get it for the most part and when you mentioned a couple things I remember I did read about that like the #import.

    When my app starts I have this code run in the firstViewController.m that fetches the names
    Code:
    - (void)viewDidLoad
    {
        int location = 0;
        if (nameArray == nil) {
            nameArray = [[NSMutableArray alloc] init];
            myURL = [NSURL URLWithString: @"http://something:something@www.sbtraveler.tv/ios/test/name.txt"];
            bundeledInformation = [[NSString alloc] initWithContentsOfURL:myURL encoding:NSUTF8StringEncoding error:nil];
            
            for (int i = 0; i < 4; i++) {
                NSScanner *scanner = [NSScanner scannerWithString:bundeledInformation];
                [scanner setScanLocation: location];
                [scanner scanUpToString:@"\n" intoString:&tempString];
                location = [scanner scanLocation];
                [nameArray addObject:tempString];
                NSLog(@"Item: %@", [nameArray objectAtIndex:i]);
                LabelTest.text = @"it's created";
            }
        }
        else
        {
    
            LabelTest.text = @"Yes to Array";
        }
        [super viewDidLoad];
        // Do any additional setup after loading the view from its nib.
    }
    This sets up the NSArray to store the string values that I use for the table views. Now in secondViewController if I need to create a new instance of the firstViewController Class, then it would need to reload all the information from the web again since it is a new object.

    I might be going about this the wrong way in trying to set up global variables that all my objects can access.

    Thanks
     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    If your app needs a single set of data shared by different controllers, then Step 1 of the design is to decide where the single set of shared data will reside.

    If you put the shared data in one of your controllers, then you also have to arrange for that data to be made available to (shared with) all the other controllers.

    If you put the shared data in a single common place, such as the application object, then any of the controllers can get it, without you needing to make the controllers share the data.

    This type of design (a single repository for shared data) is a common pattern. It applies in many cases, regardless of what kind of view or view controller is being used. It's called the Singleton pattern, and it's specifically mentioned and described in the "Cocoa Design Patterns" heading of the Cocoa Fundamentals Guide:
    http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CocoaFundamentals/

    Depending on what the shared data actually is, another possible place to store the shared data is in the application's NSUserDefaults object. See the class reference doc.

    In any case, you need to think about the design of the app before writing code for any classes. Think about what's shared and what's not. Where shared things will reside. Where unshared things will reside. Draw simple block diagrams showing relationships of where things are stored, which things can access them, etc. It doesn't need to be complicated, and you don't need a fancy drawing app. Paper and pencil suffices.
     
  7. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #7
    I couple weeks ago I started to put the design to paper for the project. I do these little tests to see how things work. I used the NSUserDefaults on a projects a few moths ago. I did not think of using that object as a common place to put Ivars that all objects could access.

    I will look through the information. Thanks for giving me a push in the right direction.
     
  8. North Bronson macrumors 6502

    Joined:
    Oct 31, 2007
    Location:
    San José
    #8
    [1]
    Try factoring out your networking code into a custom model class. Your view controller is just responsible for instantiating this model; the model is responsible for handling the download and parsing:

    Code:
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        if (myModel == nil)
        {
            myModel = [[FirstModel] alloc] init];
        }
    }
    [2]
    Be careful with the synchronous download APIs. Try incorporating asynchronous NSURLConnections to download your information from the server.

    [3]
    Try having your child view controller declare a read-write property for a model object that it needs to display its data. Then, have the parent view controller set this property to the right data when the child view controller is about to be displayed.
     
  9. chown33, Sep 8, 2011
    Last edited: Sep 8, 2011

    chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #9
    As a general-purpose place to put shared variables, NSUserDefaults is a poor choice. That's just hammering a square peg into a round hole.

    That's why you need to think about the design before thinking about how to implement a design. In other words, step 1 is creating a design. Step 2 is implementing it. You don't choose NSUserDefaults or some other class until step 2.

    When you do it backwards, then the first choice you make is NSUserDefaults, and you then cobble together a design around its strengths and weaknesses. If what you're trying to do happens to be a bad fit for NSUserDefaults, then you will spend more time and effort trying to make it fit than if you just started over from scratch.

    If you have a good clear design, it should be obvious whether to use NSUserDefaults or not. Without a clear design, you can't possibly make a sensible choice of how to implement it.

    I'll use another analogy: if you're making a video short story, do you start by shooting actors in on-location scenes? Or do you start with an idea of the story you want to tell, then write a script, then decide which actors and locations to use? Even with a script, actors, and locations chose, are you ready to shoot yet? Not likely: you have to decide which shots are closeup, which are distant, from what point of view, what time of day, whether you need a dolly and crane operator, etc. When you do it backwards, you end up with nothing but a bunch of meaningless crane and dolly shots, of incongruous actors saying meaningless dialog.
     
  10. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #10
    The more feedback I get the more I need to learn. I am at a frustrating point where I understand the concepts but get a little lost applying them.

    Chown33 - I hear you. 'Top Down Design'. My pascal teacher would hit us over the head all the time. 90% planning and 10% coding. I am still learning a lot about coding so I am creating these small project to better understand as I work myself to my over all goal. This is helping me with planning. I use OmniGraffle to help me design what I want. I am very thankful and I think you can see after all this time that I am working hard. It's tough learning object C from a book and the internet forums.

    North Bronson - Thanks for the pointers. I just started iphone a couple weeks ago but start object - C before summer. "synchronous vs. asynchronous". You lost me there and I will look it up and learn it. But thanks for the push in the right direction.
     

Share This Page