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.
 

MattInOz

macrumors 68030
Jan 19, 2006
2,760
0
Sydney

larswik

macrumors 68000
Original poster
Sep 8, 2006
1,552
11
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!
 

iphonedude2008

macrumors 65816
Nov 7, 2009
1,134
449
Irvine, CA
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.
 

larswik

macrumors 68000
Original poster
Sep 8, 2006
1,552
11
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.