Pushing ViewController with initial values

Discussion in 'iOS Programming' started by larswik, Jul 31, 2012.

  1. larswik macrumors 68000

    Joined:
    Sep 8, 2006
    #1
    I have done this before but for some reason I am missing something. I am trying to push a new viewController on the stack while setting up some initial values.

    The user selects a name from a UIPicker then then presses a UIButton. This button pushes a new VC on the stack and should display the name in a UILabel for now. When I use NSLog to verify my data I can see that the correct value for name is displayed. But ion the second VC the NSLog says it is 'null' which means not an object. I was expecting the value in VC2 to be initialized with the value from VC1 as VC2 was pushed on the stack.

    I declare characterName and set a retain property for it, how can it be 'null'? I know I am over looking some detail but after hours of searching I thought I would ask for help.

    VC1 Button code
    Code:
    - (IBAction)continueButton:(id)sender {
        NSString *name = [characterArray objectAtIndex:[charPicker selectedRowInComponent:pickerSelected]]; //pickerSelector is an int
        MainVC *mainVC = [[MainVC alloc]init];
        [mainVC setCharacterName:name];
       [COLOR="Red"] NSLog(@"string 'name' is: %@", name);[/COLOR]
        [self.navigationController pushViewController:mainVC animated:YES];
    
    }
    
    VC2.h
    Code:
    @interface MainVC : UIViewController{
        NSString *characterName;
        IBOutlet UILabel *charName;
    
    
    }
    @property (retain)NSString *characterName;
    
    @end
    
    
    VC2.m
    Code:
    @implementation MainVC
    
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            charName.text = characterName;
           [COLOR="Red"] NSLog(@"characterName is: %@", characterName);[/COLOR]
        }
        return self;
    }
    @end
    
    The console result is this
    Code:
    2012-07-31 00:27:38.211 XPm Tracker[12400:f803] characterName is: (null)
    2012-07-31 00:27:38.212 XPm Tracker[12400:f803] string 'name' is: New Character
    
    EDIT: I am using Xcode 4.4 which I don't need to use @synthesize it seems
     
  2. Reason077 macrumors 68000

    Reason077

    Joined:
    Aug 14, 2007
    #2
    initWithNibName is called before characterName has been set. That's why it prints 'null'.

    You should move your set-up code to, say, viewWillAppear, rather than put it in an init method.
     
  3. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #3
    Just tried that and still nothing. I also added a test int code to see if it was something with the NSString and it did not work?

    I placed it in an if statement to test to see if it the NSString object existed.
    Code:
    -(void)viewWillAppear:(BOOL)animated{
        NSLog(@"The int is %d", test);
        if (characterName) {
            charName.text = characterName;
            NSLog(@"characterName is: %@", characterName);
        }
        else{
            NSLog(@" not there");
        }
    
    }
    
    The console result was
    It seems that no NSString object gets created to initialize that values too? The int should have been set to a value of 5.

    My modified method to push the new VC on the stack.

    Code:
    - (IBAction)continueButton:(id)sender {
        NSString *name = [characterArray objectAtIndex:[charPicker selectedRowInComponent:pickerSelected]];
        MainVC *mainVC = [[MainVC alloc]init];
        NSLog(@"string 'name' is: %@", name);
        [self.navigationController pushViewController:mainVC animated:YES];
        mainVC.characterName = name;
        mainVC.test = 5;
    
    }
    
    Last 5 hours I have goggled the heck out of this subject and looked at many examples. I can not see any issue that pops out at me. I wonder if it is something with xcode 4.4 that I have over looked?
     
  4. Reason077 macrumors 68000

    Reason077

    Joined:
    Aug 14, 2007
    #4
    You're pushing the view controller before you're setting it's properties.

    Move the pushViewController call below the "mainVC.characterName = name;" line!
     
  5. larswik, Jul 31, 2012
    Last edited: Jul 31, 2012

    larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #5
    UPDATE: I took it back to xcode 4.3.3. I added in the @synthsize that xcode 4.4 said you don't need. adjusted my NSArray from the new literal style of adding objects to the old way "arrayByAddingObjects" method. When I ran it and it worked just fine. Then I opened it in xcode 4.4 again and it worked.

    Something is up with 4.4 and the new features, or I am missing something. I will see what it is tomorrow morning if I can't figure it out.

    I tried that before you mentioned it :)

    Code:
    - (IBAction)continueButton:(id)sender {
        NSString *name = [characterArray objectAtIndex:[charPicker selectedRowInComponent:pickerSelected]];
        MainVC *mainVC = [[MainVC alloc]init];
        mainVC.characterName = name;
        mainVC.test = 5;
        NSLog(@"string 'name' is: %@", name);
        [self.navigationController pushViewController:mainVC animated:YES];
    }
    
    Results are the same
    The bigger think that is getting me is that I test for the NSString *characterName with an if statement and the NSLog is telling me "not there", so it is not even being instantiated to be used?

    I believe that it is being passed to the second VC but since the NSString object is not being retained even thought I have used the

    Code:
    @property(nonatomic, retain) NSString *characterName;
    
    If I try and comment out the @property I get an error in the first VC saying that it cant find it basically. I am getting null because it is not being retained, or so I think.
     
  6. Reason077 macrumors 68000

    Reason077

    Joined:
    Aug 14, 2007
    #6
    What does the rest of your mainVC.h look like?
     
  7. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #7
    I updated my last post above yours. I took it into 4.3.3 and made a few changes that you didn't have to add in 4.4 like @synthesize and changed this

    Code:
            characterArray = @[newChar];
    
    to this

    Code:
            [characterArray arrayByAddingObject:newChar];
    
    and it worked just fine. It is something wrong with with xcode 4.4 or something that I need to set up that I am unaware of?
     
  8. Reason077 macrumors 68000

    Reason077

    Joined:
    Aug 14, 2007
    #8
    I think the problem was that you're accessing characterName directly rather than "self.characterName".

    In mainVC.h you probably have declared characterName twice - once as a variable and once as an @property.

    With the new "no @synthesize required" behaviour in XCode 4.4 this would actually creates two distinct variables.

    So, if you changed characterName to self.characterName (and remove the variable declaration from the .h file), I bet it'd work.
     
  9. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #9
    Yep, you nailed it. I had declared an ivar of type NSString and also set up a property for it. When I commented out the ivar it worked.

    Code:
    #import <UIKit/UIKit.h>
    
    @interface MainVC : UIViewController{
        //NSString *characterName;
        int test;
        IBOutlet UILabel *charName;
    }
    @property(nonatomic, retain) NSString *characterName;
    @property int test;
    
    @end
    
    I have to say I find that kind of dumb. You should need to declare your ivars NSString *myString; and if you want xcode to create setters and getters for the ivar you should set up @properties for the ivar you declared. It makes it confusing to also have a short cut to skip your ivar decelerations and doing it on one step with @properties.

    When I started learning xcode I would declare it NSArray *myArray and then in the implementation I would alloc/init my object use it and release it when I was done with it.

    But anyway, you were correct with the double deceleration, to bad xcode didn't warn me about it. But, it works fine as long as I keep the @synthesize in there. If I comment those out it fails to instantiate my object with the correct value. 4.4 was supposed to do away with the @synthesize I thought?

    O well, I am here to learn and I learned something new so it is a good thing.

    Thanks for your help.
     
  10. Reason077 macrumors 68000

    Reason077

    Joined:
    Aug 14, 2007
    #10
    Indeed. The new style is simpler and I understand why they've done it this way, but there should be a compiler warning if an ivar name conflicts with an @property and you're not using @synthesize.
     

Share This Page