2

I'm having trouble implementing the protocol and delegate relationship described in this post: Passing Data between View Controllers

Under the "Passing Data Back" section, # 6 says:

The last thing we need to do is tell ViewControllerB that ViewControllerA is its delegate before we push ViewControllerB on to nav stack.

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

Can you help me describe where this last portion of code goes? I have tried and tried, and read the entire post many times and can't seem to figure this out without getting several errors. Thanks for your help.

Update: I placed the code in viewDidLoad method in my ViewControllerB (child) equivalent, and received these errors::

  • No visible @interface for 'ViewControllerB' declares the selector 'initWithNib:bundle:'
  • Indexing expression is invalid because subscript type 'void' is not an integral or Objective-C pointer type
Community
  • 1
  • 1
Craigvu
  • 25
  • 4

4 Answers4

2

No visible @interface for 'ViewControllerB' declares the selector 'initWithNib:bundle:'

The issue here is that you are calling the incorrect method. The method for UIViewController is initWithNibName:bundle:

Pedro Mancheno
  • 5,237
  • 4
  • 24
  • 31
2

Don't put the code in your ViewControllerB class, that will cause a recursive loop. This is a loop that calls itself, perpetuating the loop. Inside viewDidLoad, the code gets executed when a view is loaded. So you're loading a view, then creating a new ViewControllerB object, and loading that, which will in turn create a ViewControllerB...

Try putting this code inside the ViewControllerA class, inside -viewDidAppear.

Each time you come back, the code will execute again, creating a new ViewControllerB and pushing to the stack.

Take a look at the last post I made on my blog, http://appsylvania.com. It's about understanding delegates using a real world analogy. I'll update this later with the correct URL of the exact post.

EDIT: also want you to know what the special keyword self is. It's sort of like this in JavaScript. When you use self, you are making a reference to the current class you are in. So, if you are working in the .m file of ViewControllerB, and you type self, then self == instance of ViewControllerB. You originally said you were trying to make ViewControllerA the delegate of B. In this case you are making your current instance of ViewControllerB the delegate of a new instance of ViewControllerB.

Daddy
  • 9,045
  • 7
  • 69
  • 98
  • Very helpful. Thank you. Instead of self would I use VewControllerB? I want to have VIewControllerB as a child of ViewControllerA – Craigvu Aug 29 '13 at 22:11
  • It's hard to explain in a comment, but I would like to write a blog post about it. You want an `* instance` of ViewControllerA to be the delegate of ViewControllerB. When you are inside `viewDidLoad` of your ViewControllerA.m file, using `self` is a reference to the instance itself, after it is allocated and instantiated. The big stumbling block is to understand the "Object Oriented Programming" concept of Classes versus Instances. In short, a Class is like a blueprint to a skyscraper, and a skyscraper is an instance of the blueprint. You can have many buildings from one set of plans – Daddy Aug 29 '13 at 23:02
  • So every time you type `ViewControllerA *viewA = [[ViewControllerA alloc] init];` you have created a new instance. You are using a class (blueprint) to create an instance (skyscraper). I don't know what I'm trying to get across, other than this will all be greek to you unless you really understand how Object Oriented Programming (OOP) works. If you can understand the concept then you can most likely make your way in any OOP language if you know the syntax – Daddy Aug 29 '13 at 23:06
1

Th whole point is that viewControllerA is creating and showing viewControllerB. However it's done, whether segue or created explicitly from NIB, the delegate is set just after the viewControllerB` is created and before it is displayed.

Wain
  • 118,658
  • 15
  • 128
  • 151
0
  1. The selector initWithNib:bundle: is indeed wrong. If you look at the UIViewController documentation, you'll see that it should be initWithNibName:bundle:.

  2. You've omitted a semicolon after viewControllerB.delegate = self.

Chuck
  • 234,037
  • 30
  • 302
  • 389