1

I want to access a function in ViewController 1 from ViewController 2. This works (confirmed by breakpoints and NSLog output). But accessing an object which is defined in ViewController 1 is nil when called from ViewController 2.

ViewController 1.h

#import "SRWebSocket.h"

@interface ViewController : UIViewController <UITextFieldDelegate, SRWebSocketDelegate> 
@property (nonatomic,strong) SRWebSocket *socket;

-(void)sendMessageToServerWithContent:(NSString *)message;

ViewController 1.m

- (IBAction)connect:(id)sender {

    socket.delegate = nil;
    socket = nil;

    socket = [[SRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:serverIP_GLOBAL]]];

    socket.delegate = self;

}

-(void)sendMessageToServerWithContent:(NSString *)message{

//irrelevant code for question removed
[self.socket send:jsonString];

}

ViewController 2.h

#import "ViewController.h"

@property (nonatomic,strong) ViewController *viewVC;
@interface ContactsTableViewController : UITableViewController

ViewController 2.m

- (void)viewDidLoad {
    [super viewDidLoad];

    viewVC = [ViewController alloc];

    [viewVC sendMessageToServerWithContent:@"Test"]; 
    //When calling from here, the socket object in ViewController 1 is nil

}
2
  • When the socket property is initialized? Try to check what happens first, socket initialization or ViewController 2 viewDidLoad method. Commented Dec 26, 2014 at 12:25
  • socket = [[SRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:serverIP_GLOBAL]]]; This happens in ViewController 1 before opening the second. Commented Dec 26, 2014 at 12:28

2 Answers 2

4

You can't initialize the object like: viewVC = [ViewController alloc];

You have to pass the object of ViewContoller1 to ViewContoller2 i.e.

When you are pushing the ViewContoller2 on viewcontoller1 you have write storyboard deletgate code

 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {

        ViewController2 *view2=[segue destinationViewController];
        view2.viewVC=self; // pass viewcontoller1 object to viewcontoller2
    }

And In ViewContoller2 You will access the viewContoller1 object in viewVC variable and you can directly call it like this

- (void)viewDidLoad {

    [super viewDidLoad];
    [viewVC sendMessageToServerWithContent:@"Test"]; 
    //When calling from here, the socket object in ViewController 1 is nil

}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, also my VC1 was not inside a storyboard including it into a storyboard and using your answer it worked.
thanks IR Works Looking forward your vote on my post.
As Girijesh says, calling alloc on an object but not init is invalid (voted). Creating an object in Objective-C is always a 2-step process: alloc, then an init method. If you don't call init, it's an error. Always.
3

You call viewVC, which even is not properly created and initialized. That's not the previous view controller the screen before.

1.To call the object's method, it should be properly initialized first.

viewVC = [[ViewController alloc] init];

You said, the socket property initialized in viewDidLoad method. To force load the view, use the loadView method, if you haven't an intention to present the view first.

2.Don't initialize another ViewController if you want to use the certain object. In your case it should be controller from which the second controller presented.

Somewhere in ViewController.m file, when the second view controller is about to present:

ViewController2 *second=[[ViewController2 alloc] init];
second.vc1 = self; // now the second controller has a pointer to original object
[self presentViewController:second ...];

For segue-navigation

- (void)prepareForSegue:(UIStoryBoardSegue *)segue
{
  ViewController2 *second=(ViewController2 *)segue.destinationViewController;
  send.vc1 = self;
}

Now in ViewController 2 viewDidLoad method

- (void)viewDidLoad 
  {
    [super viewDidLoad];
    [self.vc1 sendMessageToServerWithContent:@"Test"]; 
  }

UPD

Why don't you keep your socket in a separate singleton object? That's much more simpler to use. It would be like:

[[MySpecialSocketManager sharedInstance] sendMessageToServerWithContent:@"Hello, Server!"];

See, how to implement singleton here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.