Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Lakario

macrumors member
Original poster
Oct 29, 2008
30
0
I am having some difficulty trying to figure out how to pass an item between the Views in my applications. My program is a NavigationController based app that starts out with a table containing information about each item. When the user clicks on an item I want to take them to an ItemViewController nib that takes an Item object and populates the fields on the page based on the properties of the Item. The trouble is, no matter how many different ways I try to set the Item property of ItemViewController, it always end up null when the view loads. The item object is obtained programatically in the table view's click event on each row and then I initialize the ItemViewController and call its setItem method to specify the object. I attempted to implement my own setter method and when I stepped into it a call to self.item returned the correct object, but as soon I try to retrieve the item with my getter it is null.

Where did my object go?

Additionally, could someone show me how to manually implement my properties so that they are not generated for me? I'd like to slap some breakpoints in the setters to see if I can get a better feel for what's going on.

RootViewController.m (excerpt)
Code:
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

// Navigation logic -- create and push a new view controller
iPhoneHelloWorldAppDelegate *appDelegate = (iPhoneHelloWorldAppDelegate *)[[UIApplication sharedApplication] delegate];
Item *item = (Item *)[appDelegate.items objectAtIndex:indexPath.row];

if(self.itemView == nil) {
	ItemViewController *viewController = [[ItemViewController alloc] initWithNibName:@"ItemViewController" bundle:[NSBundle mainBundle]];
	self.itemView = viewController;
	[viewController release];
}

[self.itemView setItem: item]; // self.itemView.item is always nil. even when item is not
[self.navigationController pushViewController:self.itemView animated:YES];
self.itemView.title = [item itemName];
//[item release];
//[self.itemView.itemDescription setText:[item itemDescription]]; // This call works fine.
]

ItemViewController.h
Code:
@interface ItemViewController : UIViewController {
	IBOutlet UITextView		*itemDescription;
	Item				*item;
	SellViewController		*sellView;
	NSString *unique;
}

@property (nonatomic, retain) IBOutlet UITextView	*itemDescription;
@property (nonatomic, retain) IBOutlet Item		*item;
@property (nonatomic, retain) SellViewController	*sellView;
@property (readwrite, assign) NSString *unique;

-(IBAction) sellItem : (id)sender;
@end

Item.h
Code:
@interface Item : NSObject {
	NSString *itemName;
	NSString *itemDescription;
	int *itemPrice;
	NSString *unique;
}

@property (nonatomic, retain) NSString *itemName;
@property (nonatomic, copy) NSString *itemDescription;
@property (readwrite, assign) int *itemPrice;
@property (nonatomic, retain) NSString *unique;

-(id)initWithName:(NSString*)name description:(NSString*)desc price:(int*)price;
 

Niiro13

macrumors 68000
Feb 12, 2008
1,719
0
Illinois
Don't IBOutlet the item.

Other than that, it should work. I use it all the time and that's pretty much how I pass the item (except I don't use IB).
 

Lakario

macrumors member
Original poster
Oct 29, 2008
30
0
If you'll look at my first code block you'll see that I am in fact doing that:

Code:
if(self.itemView == nil) {
	[B]ItemViewController *viewController = [[ItemViewController alloc] initWithNibName:@"ItemViewController" bundle:[NSBundle mainBundle]];[/B]
	self.itemView = viewController;
	[viewController release];
}

[COLOR="Red"][self.itemView setItem: item];[/COLOR]
[B][self.navigationController pushViewController:self.itemView animated:YES];[/B]
 

Lakario

macrumors member
Original poster
Oct 29, 2008
30
0
I've tried removing IBOutlet, but that hasn't made any difference with the problem I have been experiencing.
 

fenrus110

macrumors regular
Mar 24, 2008
142
0
we're talking about this
@property (nonatomic, retain) IBOutlet Item *item;

Item extends NSObject
 

firewood

macrumors G3
Jul 29, 2003
8,141
1,384
Silicon Valley
The trouble is, no matter how many different ways I try to set the Item property of ItemViewController, it always end up null when the view loads.

1. The view controller object may not exist until it loads, so trying to set a item property in a non-existant object is probably futile.

2. Instead of trying to reach inside a view controller and muck with its item's properties, you could have the view controller check an external data model object and update its own items or views accordingly. I think that would be closer to the MVC paradigm.

.
 

Lakario

macrumors member
Original poster
Oct 29, 2008
30
0
1. The view controller object may not exist until it loads, so trying to set a item property in a non-existant object is probably futile.

2. Instead of trying to reach inside a view controller and muck with its item's properties, you could have the view controller check an external data model object and update its own items or views accordingly. I think that would be closer to the MVC paradigm.

.

Would it be sufficient to have the view ask the app delegate for the item currently selected by the user at the top of the navigation? The problem with that approach is that these views can be reached in a number of ways but I need them to function the same regardless. I don't want to explicitly call a parent object in the view's definition just to retrieve a value, rather I'd like the object that creates the view to set its properties.
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
Can you show the declaration for the root view controller's property setItem? The IBOutlet text in your properties, while not idiomatic, probably won't cause a problem.
 

Lakario

macrumors member
Original poster
Oct 29, 2008
30
0
Can you show the declaration for the root view controller's property setItem? The IBOutlet text in your properties, while not idiomatic, probably won't cause a problem.

RootViewController does not define setItem, ItemViewController does. iPhoneHelloWorldAppDelegate contains an NSMutableArray of Items and I retrieve the relevant item on the draw and click events of the table cell within the RootViewController.

iPhoneHelloWorldAppDelegate.m (excerpt)
Code:
@property (nonatomic, retain) NSMutableArray *items;

ItemViewController.m (excerpt)
Code:
@interface ItemViewController : UIViewController {
	IBOutlet Item			*item;
}

@property (nonatomic, retain) IBOutlet Item *item;

I just realized that I was somewhat misunderstanding my program flow originally. I previously thought the RootViewController contained my Item array when in fact it was the AppDelegate that did. (I followed a tutorial for the initial pieces of this application). That being said, should I be asking the AppDelegate for the Item reference rather than trying to pass it into my view? That would be a better MVC architecture (assuming the AppDelegate is my Controller and the ItemView is, well, the View), but that comes back to the issue of wanting to make my Views more abstract. What if I have two controllers that could bring the user to the ItemViewController nib? (Or does the iPhone SDK even want you to have more than one controller per application?). My only experience with MVC is in the J2EE framework where your servlet acts as the controller and it is perfectly acceptable there to have multiple controllers (servlets).

I think what is most confusing to me is the fact that I have no problem setting my ItemViewController's UITextView.text property from the RootViewController, but when I try to pass a whole object (like my Item) from one view to the next I lose the object. Why would I be able to pass a string without any difficult but be completely unable to pass a custom object?

Eventually this application will have a base Game object that defines a player and each Player has a set of Items with their own properties. Additionally, other Players (not the user) will have their own Item set as well. That being said should I move in the direction of having a PlayerController, an ItemController, an XYZController, etc that is all defined within my AppDelegate? If that's the case then I believe it would be prudent to modify the application at its root.

Thanks guys!
 

Lakario

macrumors member
Original poster
Oct 29, 2008
30
0
Well the good news is I figured out what was wrong and my Item is being set correctly now. The bad news is how retarded the problem was. Maybe someone can explain this behavior because I don't really follow it...

My ItemViewController defined an Item object and referenced it in the File's Owner. Every time the view loaded the Item object in my View was overwriting anything I had set before loading the View. Why would that happen?

What a friggen waste of 3 days...
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.