IR Works
IR Works

Reputation: 49

How to access objects in other class?

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

}

Upvotes: 1

Views: 213

Answers (2)

Girijesh Kumar
Girijesh Kumar

Reputation: 165

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

}

Upvotes: 4

Daniyar
Daniyar

Reputation: 3003

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

Upvotes: 3

Related Questions