-1

I posted a question earlier about the same thing, but now I have made a simple project to show what I am doing, so the problem can be found easier.

I have two viewControllers, one is called ViewController and the other SecondViewController. I tried sending a NSString called testy to a viewController and logging it, but it returned null.

Here is my code trying to send the string from viewController to secondViewController

ViewController.m

#import "ViewController.h"

#import "SecondViewController.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize cellName;

- (void)viewDidLoad
{
    [super viewDidLoad];

    cellName = @"testy";

    SecondViewController *obj = [[SecondViewController alloc] init];

    obj.cellName2 = self.cellName;    
}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController {

}
@property(nonatomic,retain) NSString *cellName;

@end

SecondViewController.m

#import "SecondViewController.h"

#import "ViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

@synthesize cellName2;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

}

- (void)viewDidAppear:(BOOL)animated {
NSLog(@"%@",cellName2);

}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

SecondViewController.h

#import <UIKit/UIKit.h>

@interface SecondViewController : UIViewController {

}

@property(nonatomic,retain) NSString *cellName2;

@end

Edit

I would like to say that my storyboard has two viewController that each have a button. Each button modally brings you to the other view.

i_duhh_bomb
  • 300
  • 1
  • 10
  • 1
    Have you tried to add a breakpoint and look at the variables and properties involved? And if so, what did you see? – Monolo Aug 13 '13 at 20:42
  • dont know how to use those – i_duhh_bomb Aug 13 '13 at 20:43
  • Are you using ARC? If so, you should be using `strong` instead of `retain`. If not, you should be sending `autorelease` when you initialize `SecondViewController *obj`. – bdesham Aug 13 '13 at 20:43
  • Same results as before – i_duhh_bomb Aug 13 '13 at 20:46
  • 1
    @user2660874 The debugger is a very valuable tool for this sort of problem, so worth looking into. Anyway, the reason I asked is that in 99% of the cases a bug like this is an uninitialized variable. Easy to find with the debugger. And I prefer you spend a minute with the debugger before I have to spend 5 minutes reading all your code :-) – Monolo Aug 13 '13 at 20:46
  • In your `viewDidLoad` of your 1st vc, your `obj` object (very descriptive name) vanishes when that method is done. Create a property to access it later. – ott-- Aug 13 '13 at 20:55
  • How is this done? And thanks, I took me days to come up with `obj` – i_duhh_bomb Aug 13 '13 at 20:57
  • Yeah time spent learning to use the debugger with not be wasted time – Grady Player Aug 13 '13 at 20:57
  • I will definaitely look into it, do you know of a good tut for it? – i_duhh_bomb Aug 13 '13 at 20:58
  • What do you mean by "I tried sending a NSString called testy to a viewController and logging it, but it returned null."? You have message in a log, but with empty string? Or you have clear log? – Oleksandr Palii Aug 13 '13 at 21:00
  • sorry for any confusion, the log says (null) – i_duhh_bomb Aug 13 '13 at 21:00

5 Answers5

2

Are you sure viewDidLoad is being called? I think it's not called until the view is loaded. I don't think it's called after an alloc init. Also you are setting the string in obj 2 after init. Even if what you are thinking is correct, the 'viewDidLoad' method may be called before the string is being set.

If you want a variable set on init you need to override viewController 2's init method to something like initWithMyVariable then the var will be set on init.

From: Passing Data between View Controllers

Passing data forward to a view controller from another view controller. You would use this method if you wanted to pass an object/value from one view controller to another view controller that you may be pushing on to a navigation stack.

For this example we will have ViewControllerA and ViewControllerB

To pass a BOOL value from ViewControllerA to ViewControllerB we would do the following.

in ViewControllerB.h create a property for the BOOL

@property(nonatomic) BOOL *isSomethingEnabled;

in ViewControllerA you need to tell it about ViewControllerB so use an

import "ViewControllerB.h"

Then where you want to load the view eg. didSelectRowAtIndex or some IBAction you need to set the property in ViewControllerB before you push it onto nav stack.

ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
viewControllerB.isSomethingEnabled = YES;
[self pushViewController:viewControllerB animated:YES];

This will set isSomethingEnabled in ViewControllerB to BOOL value YES.

Community
  • 1
  • 1
Woodstock
  • 22,184
  • 15
  • 80
  • 118
  • Im sure it is, because if I put nsLog "hello world" it logs it – i_duhh_bomb Aug 13 '13 at 20:56
  • 3
    Its definitely not called by alloc/init. The view has to be displayed somehow. – Mario Aug 13 '13 at 20:56
  • @user2660874 where do you push/present your second viewController? – Mario Aug 13 '13 at 20:56
  • 2
    You don't. Add `[self presentViewController: obj animated: YES completion: nil];` at the end of your first viewControllers viewDidLoad. And also, change `cellName = @"testy";` to `self.cellName = @"testy";` – Mario Aug 13 '13 at 20:59
1

It might be worth for all who read this article to mention working patterns passing variables between two views:

Options:

  1. Use global variable: SO answer
  2. Use delegation pattern: SO answer
  3. Use notification infrastructure: article
  4. Persist the value in app's userdefault storage, then read when you need : SO answer

For this particular situation it might be better not to create secondviewcontroller in the firstviewcontroller's viewdidload, but to keep the cellName until that point when a user action happens (eg. button press) and then in that method you just set the newly created secondviewcontroller's cellName2 property.

SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:@"second" bundle:nil];
secondViewController.cellName = self.cellName;

I've tested and it is properly logging the value in secondviewcontroller's viewdidload.

Community
  • 1
  • 1
nzs
  • 3,252
  • 17
  • 22
0

Instead of doing: cellName = @"testy"; You should Call:

 self.cellName = @"testy";

Also, When you alloc and init in:

SecondViewController *obj = [[SecondViewController alloc] init];, the viewDidLoad() for secondViewController is called right at that time and you are initializing it's iVar later in the line obj.cellName2 = self.cellName;

That's why you are having NSLOG as null.

Print the NSLOG in viewWillAppear() of secondViewController and you will see the right value this time.

Jamal Zafar
  • 2,179
  • 2
  • 27
  • 32
0

-Create a initialization method for second view controller to pass the variable..

in secondview controller .h file

add init method

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil cellString(NSString* )cellName;

and .m file

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil cellString(NSString* )cellName{

   self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

     if (self) {

        // Custom initialization
     cellName2=cellName;

     }
     return self;

}

and in ViewController.m for initialization

SecondViewController *obj = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil cellString:self.cellName];

This should work... Best of luck

Dipu Rajak
  • 693
  • 5
  • 15
-1

In viewcontroller.m you have the following in viewDidLoad:

..
..
SecondViewController *obj = [[SecondViewController alloc] init];
obj.cellName2 = self.cellName;    
}

The SecondViewController "obj" is never being presented before the end of viewDidLoad, hence NSLog printing null.

If you are wanting to pass a value to SecondViewController via a storyboard, you will need to use the prepareForSegue method. A good example of using it can be found here.

Mongo
  • 2,674
  • 1
  • 20
  • 22