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
This weekend I set out to understand how to pass data back from ViewController2 to ViewController1 when I exit VC2. I found a good explanation on line with helper code but I am not understanding a few things even though it works.

So in VC1.h I import the header of VC2. I created in the xib a UIlabel and a UIbutton. The user presses the button and it pushes VC2 on the stack, easy
Code:
#import <UIKit/UIKit.h>
#import "SecondVC.h"

@interface ViewController : UIViewController [COLOR="Red"]<MyUsefulDelegate>[/COLOR]{
    IBOutlet UILabel *displayLable;
}
-(IBAction)pressButton:(id)sender;
@end
VC1.m
Code:
#import "ViewController.h"

@implementation ViewController

- (void)viewDidLoad
//...Boilerplate code removed.

-(IBAction)pressButton:(id)sender{
    SecondVC *svc = [[SecondVC alloc] init];
   [COLOR="Red"] [svc setMuDelegate:self];[/COLOR]
    [self.navigationController pushViewController:svc animated:YES];
}

- (void)infoReturned:(id)objectReturned {
    NSArray *tempArray = [NSArray arrayWithArray:objectReturned];
    displayLable.text = [tempArray objectAtIndex:0];
}

@end

In VC2 I just have a textField, that is it. The user enters some string and presses the back button on the NavController (NavController set up in the AppDelete).
Code:
#import <UIKit/UIKit.h>

[COLOR="Red"]@protocol MyUsefulDelegate <NSObject>
- (void)infoReturned:(id)objectReturned;
@end
[/COLOR]
@interface SecondVC : UIViewController{
    [COLOR="Red"]id <MyUsefulDelegate> muDelegate;[/COLOR]
    IBOutlet UITextField *textField;
}
@property (assign) id <MyUsefulDelegate> muDelegate;

@end

in the VC2.m I simply get the string in the textField and add it to an array and it is sent back to VC1 and displayed in the UILabel.

Code:
#import "SecondVC.h"

@implementation SecondVC
//...Boilerplate code removed.
-(void)viewWillDisappear:(BOOL)animated{
    NSArray *myArray =[[NSMutableArray alloc] initWithObjects:textField.text, nil];
 [COLOR="Red"]   [[self muDelegate] infoReturned:myArray];[/COLOR]
}

@end

It all works but a few things I don't get why?

Q1. When VC2 is instantiated a @protocol is defined with 1 Method. In the @interface, in the ivar section, dose that then creating an object called muDelegate of type MyUsefulDelegate which is the protocol? I don't understand the 'id' part of that line? I know id is a generic object type and used in Methods, like in the Protocols method they use id. But it seems to be setting a return type in the ivar section where you declare your global instance variable, I don't get that?

Q2. When the button is pressed, in VC1.m the VC2 object is instantiated. Since I declared an muDelegate object in the ivar section I gain access to that and then set it to 'self'. This has me totally confused, self? I could see this [svc setMuDelegate.delegate:self]; There you are telling the delegate to be 'self', or in charge of it's self.

The @property section I get, it is creating the setters and getters to access this Method.

Q3. After I get my string from the textField and add it to myArray there is the line of code
Code:
[[self muDelegate] infoReturned:myArray];
When I normally do something to my objects, like add to myArray(if it was a mutableArray) I would write something like [array addObject:someObject]; But if I try and write code like this,
Code:
[muDelegate infoReturned:myArray];
The code won't work. Why must I refer to that object with 'self' first? I don't refer to myArray that way [[self myArray] addObject: someObject];?

Q4. That new @protocol what was created, that is now destroyed when I exit out of VC2 is gone, no longer accessible? Every time I instantiate a new VC2 a new @protocol is created. I am pretty sure that is right.
 
I got the breakdown on http://stackoverflow.com for it. I did search and I do get what is happening with the majority of it. The code works in my test project just fine, but I wanted to understand it so I can replicated it in the future easily. I did Google last night but didn't quite get it still. The 2 lines of code that are throwing me off are these

Code:
id <MyUsefulDelegate> muDelegate;
[[self muDelegate] infoReturned:myArray];

The first looks like it is making a 'pointer' variable to the @protocol that was created. But there is no '*' (pointer)? The id that proceeds that from what I understand is a generic object type. It makes scenes if the code looked like this...
Code:
<MyUsefulDelegate> *muDelegate;

There I could at least see a pointer to that new object, space in memory, that the Delegate is located. I have not been able to find anything that describable that? The only time I see things like that are when I work with Structs, CGSize size =. But this is not a Struct?

As for the second line of code I posted, I do get that now. The encapsulation [self muDelegate] was throwing me off. When I deal with NavControllers I write [self.navigationController ....push:....]; When I wrote it like this [self.muDelegate method:argument]; I understood it. But the first on I don't get still.

Sorry, just trying to get it. Spent all night last night researching it.

Thanks!
 
I got the breakdown on http://stackoverflow.com for it. I did search and I do get what is happening with the majority of it. The code works in my test project just fine, but I wanted to understand it so I can replicated it in the future easily. I did Google last night but didn't quite get it still. The 2 lines of code that are throwing me off are these

Code:
id <MyUsefulDelegate> muDelegate;
[[self muDelegate] infoReturned:myArray];

The first looks like it is making a 'pointer' variable to the @protocol that was created. But there is no '*' (pointer)? The id that proceeds that from what I understand is a generic object type. It makes scenes if the code looked like this...
Code:
<MyUsefulDelegate> *muDelegate;

There I could at least see a pointer to that new object, space in memory, that the Delegate is located. I have not been able to find anything that describable that? The only time I see things like that are when I work with Structs, CGSize size =. But this is not a Struct?

As for the second line of code I posted, I do get that now. The encapsulation [self muDelegate] was throwing me off. When I deal with NavControllers I write [self.navigationController ....push:....]; When I wrote it like this [self.muDelegate method:argument]; I understood it. But the first on I don't get still.

Sorry, just trying to get it. Spent all night last night researching it.

Thanks!

When you do something like UILabel *label, you are making a pointer to a type of UILabel. When you do cgsize size, you are creating a new variable, not a pointer. So when doing id <MyUsefulDelegate> muDelegate, you are creating a variable which can take on any pointer type. It is not a pointer to an id, or a protocol because there would be no data to take on.

Also, when you do uilabel *label, memory is not allocated nor is an object created. It just says, "this pointer, label, points to a uilabel and can do what a uilabel (or subclasses of uilabel) can do" when you do Uilabel *label = [[uilabel alloc]init], you allocate and create that classes variables and then initialize it and allow it to change an send methods. Then, you assign that to the pointer.

EDIT: when you do id <myusefuldelegate> mudelegate, you say that this a pointer to any object that conforms to the protocol myusefuldelegate. You can not assign any object to that value, only ones that implement the required methods of that protocol.
 
I see that. It still looks odd to me but I will just have to deal with that. I understand the type is id, But when I declare a int I would say int num; So when I see' id <myusefuldelegate> ' I would see 'type varName;'. But here I am seeing 'type varName somethingElse'.

Like you say it is not s Struct ether. Everything works and I can return the data but it just bugs me that I can't wrap my head around that yet.

I'm sure it will sync in someday.

Thanks!
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.