Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

larswik

macrumors 68000
Original poster
Sep 8, 2006
1,552
11
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
 
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.
 
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
2012-07-31 01:34:14.799 XPm Tracker[13213:f803] string 'name' is: New Character
2012-07-31 01:34:14.801 XPm Tracker[13213:f803] The int is 0
2012-07-31 01:34:14.801 XPm Tracker[13213:f803] not there

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?
 
You're pushing the view controller before you're setting it's properties.

Move the pushViewController call below the "mainVC.characterName = name;" line!
 
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
2012-07-31 01:57:35.526 XPm Tracker[611:f803] string 'name' is: New Character
2012-07-31 01:57:35.537 XPm Tracker[611:f803] The int is 0
2012-07-31 01:57:35.537 XPm Tracker[611:f803] not there

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.
 
Last edited:
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?
 
It is something wrong with with xcode 4.4 or something that I need to set up that I am unaware of?

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.
 
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.
 
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.

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.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.