Register FAQ / Rules Forum Spy Search Today's Posts Mark Forums Read
Go Back   MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Apr 28, 2009, 03:03 AM   #1
rubyruby
macrumors member
 
Join Date: Jan 2009
passing Data from AppDelegate to UITabBarController

Hi,

how do I pass a data model (which I've created on my own) to the UITabBarController (which is my root view) in my AppDelegate?

The problem is, that UITabBarController (e.g. addController) doesn't include
my model (e.g. addController.model). So I would have to subclass it. Is this a proper solution?

Regards,

rubyruby
rubyruby is offline   0 Reply With Quote
Old Apr 28, 2009, 04:01 AM   #2
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
Do it the other way round. Any instance can get a pointer to the app delegate so simply provide an accessor method for the data model there.

Or make the "root" of your data model a singleton object and access it that way.
robbieduncan is offline   0 Reply With Quote
Old Apr 28, 2009, 05:23 AM   #3
rubyruby
Thread Starter
macrumors member
 
Join Date: Jan 2009
Thanks, the way you've described it, is my current solution. But I've read, that it would be better design to have a model, which "wanders" around the views instead of a central one.

Anyway, the central approach of getting a instance of AppDelegate works. I'll stick with it, until I see some better solutions.
rubyruby is offline   0 Reply With Quote
Old Apr 28, 2009, 07:44 AM   #4
Luke Redpath
macrumors 6502a
 
Join Date: Nov 2007
Quote:
Originally Posted by robbieduncan View Post
Do it the other way round. Any instance can get a pointer to the app delegate so simply provide an accessor method for the data model there.

Or make the "root" of your data model a singleton object and access it that way.
Mmm, whilst sometimes necessary, making everything singletons or accessing the app delegate all over the place seems like a code smell to me.

If you need to pass data into your controller from your app delegate, just add an accessor (or a property) to your own subclass of UITableViewController, e.g.:

Code:
// MyController.h

@class MyModel;

@interface MyController : UITableViewController {
  MyModel *model;
}
@property (nonatomic, retain) MyModel *model;
@end

// MyController.m

#import "MyModel.h"

@implementation MyController
@synthesize model;
@end

// YourAppDelegate.m

- (void)applicationDidFinishLaunching:(UIApplication *)application 
{
  Model *someModelInstance = [[MyModel alloc] init];
  MyController *controller = [[MyController alloc] initWithStyle:UITableViewStylePlain];
  controller.model = someModelInstance;
  [someModelInstance release];
  [window addSubview:controller.view];
  [controller release];
  [window makeKeyAndVisible];
}
Of course, I'm making assumptions about where your instance of your model comes from and where the controler is initialized (it might be loaded from a nib into an instance variable/property of your app delegate).
Luke Redpath is offline   0 Reply With Quote
Old Apr 28, 2009, 08:00 AM   #5
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
Quote:
Originally Posted by Luke Redpath View Post
Mmm, whilst sometimes necessary, making everything singletons or accessing the app delegate all over the place seems like a code smell to me.
I think it depends, very much, on the exact data model. If there is a single data model and only ever will be then I'd make it a singleton. If you are asking the controller to display a specific piece of data that will be different every time then I'd pass it that data to display.

The OP did not really give us enough data to work out which case he was in, so I simply suggested the easiest solution from where it sounded like he was.
robbieduncan is offline   0 Reply With Quote
Old Apr 28, 2009, 11:35 AM   #6
rubyruby
Thread Starter
macrumors member
 
Join Date: Jan 2009
Hey guys,

that's right. I didn't give you much information. I have a handful of models. Anyway, you two worked out nice solutions:

1. If there's a single model: singelton
2. If there are many models: subclassing

Cool.. Thanks Robbie and Luke
rubyruby is offline   0 Reply With Quote
Old Apr 28, 2009, 12:51 PM   #7
Luke Redpath
macrumors 6502a
 
Join Date: Nov 2007
I'd still favour the latter solution as it is more flexible in the long run; if having your model object as a singleton is no longer appropriate, you'll have to change more code. I've always considered singletons a code smell and I try and avoid them unless absolutely necessary.
Luke Redpath is offline   0 Reply With Quote
Old May 30, 2009, 03:53 AM   #8
samsonsu
macrumors newbie
 
Join Date: May 2009
Quote:
Originally Posted by Luke Redpath View Post
Mmm, whilst sometimes necessary, making everything singletons or accessing the app delegate all over the place seems like a code smell to me.

If you need to pass data into your controller from your app delegate, just add an accessor (or a property) to your own subclass of UITableViewController, e.g.:

Code:
// MyController.h

@class MyModel;

@interface MyController : UITableViewController {
  MyModel *model;
}
@property (nonatomic, retain) MyModel *model;
@end

// MyController.m

#import "MyModel.h"

@implementation MyController
@synthesize model;
@end

// YourAppDelegate.m

- (void)applicationDidFinishLaunching:(UIApplication *)application 
{
  Model *someModelInstance = [[MyModel alloc] init];
  MyController *controller = [[MyController alloc] initWithStyle:UITableViewStylePlain];
  controller.model = someModelInstance;
  [someModelInstance release];
  [window addSubview:controller.view];
  [controller release];
  [window makeKeyAndVisible];
}
Of course, I'm making assumptions about where your instance of your model comes from and where the controler is initialized (it might be loaded from a nib into an instance variable/property of your app delegate).
Saving & initializing model in view controller could be a problem if you have multiple views in your app. Upon low memory warning, view controller might re-init (if it's not the current view controller), and that causes your data model to re-create and you lose all the state.

This can be easily proven with simulator. Add a button in your app to make some change to your data model (as a member of table view controller). Switch to a different view (so table view controller will be pushed into stack). Now send a simulated low memory warning, then come back to your table view controller. Inspect the model data -- you'll find your change is gone. Model is now back to initialized state.

If you set a breakpoint in your data model's init function and repeat the above, you'll find the data model is re-init'ed when you switch back after low-mem warning.

I learnt it the hard way.

Now I store data model as a property in delegate. Everything works very well now. I believe Singleton works well too.
samsonsu is offline   0 Reply With Quote
Old May 30, 2009, 02:51 PM   #9
firewood
macrumors 603
 
Join Date: Jul 2003
Location: Silicon Valley
Quote:
Originally Posted by Luke Redpath View Post
Mmm, whilst sometimes necessary, making everything singletons or accessing the app delegate all over the place seems like a code smell to me.
And for a small app with a countably small number of objects and models, wasting a users memory and battery life by using layers of properties, subclasses, and notification handlers seems like an even smellier waste of resources to me.

Just stick a pointer to the model in a global. Or if the apps total state data is small enough, just put them all in global variables. One less level of indirection to potentially trash your CPU cache.

Not every class needs to be designed to scale to 1000's of instances collaborating remotely. Remember that all this dynamic OOP stuff, while good for the developer, can be bad for the users battery life. Spend some time thinking about them.

imho
firewood is offline   0 Reply With Quote
Old May 31, 2009, 08:14 AM   #10
Luke Redpath
macrumors 6502a
 
Join Date: Nov 2007
Quote:
Originally Posted by samsonsu View Post
Saving & initializing model in view controller could be a problem if you have multiple views in your app. Upon low memory warning, view controller might re-init (if it's not the current view controller), and that causes your data model to re-create and you lose all the state.
.
This is completely wrong.

The default behaviour of UIViewController when handling low memory warnings is to release and reinitialize it's sub-views. The entire object isn't released and re-initialized. Your properties will be safe.

Obviously if you re-initialize the controller yourself you'll need to pass the same model object back into it.

Or you could just make sure your model object is saved when the view changes.
Luke Redpath is offline   0 Reply With Quote
Old May 31, 2009, 08:15 AM   #11
Luke Redpath
macrumors 6502a
 
Join Date: Nov 2007
Quote:
Originally Posted by firewood View Post
And for a small app with a countably small number of objects and models, wasting a users memory and battery life by using layers of properties, subclasses, and notification handlers seems like an even smellier waste of resources to me.

Just stick a pointer to the model in a global. Or if the apps total state data is small enough, just put them all in global variables. One less level of indirection to potentially trash your CPU cache.

Not every class needs to be designed to scale to 1000's of instances collaborating remotely. Remember that all this dynamic OOP stuff, while good for the developer, can be bad for the users battery life. Spend some time thinking about them.

imho
I'm not a big fan of premature optimisation. Good design first, optimise later. Good design isn't necessarily about scaling, its also about making things easier to test and refactor. Sure, for a small toy app you can probably get away with stuffing everything in your app delegate but for anything else I'd stop using the app delegate for what it isn't intended.

I don't buy the argument that having a few more classes and objects (i.e. a less coupled design) will make that much impact on the user's battery life. Got any comprehensive figures to back that up?
Luke Redpath is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Having an issue passing data between views with Core Data. iJustinCabral iPhone/iPad Programming 0 Jul 15, 2013 09:50 PM
Passing Data Between Segue w3tmb iPhone/iPad Programming 1 Feb 10, 2013 12:57 PM
Passing back data from view2 back to view1 larswik iPhone/iPad Programming 5 Dec 17, 2012 10:42 AM
Call reloadData for NSTableView from AppDelegate AdrianK Mac Programming 3 Aug 11, 2012 01:32 PM
Passing Data between View Controllers : from uitableview to a details view controller EliasRahme iPhone/iPad Programming 7 Jul 20, 2012 08:04 AM

Forum Jump

All times are GMT -5. The time now is 09:18 PM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC