How to share data globally among multiple view controllers - iphone

can anybody help me out please...
i have a huge object in a model. i made it as a single ton class and returning the object wn other calls.but the object is very big thats y the app is crasing. with out returning how to share the data globally and when to alloc the object and where to dealloc the object. i dont need all the data in object in a viewcontroller ..i need specific data to a view controller from that object...
Thanks.

You can store a pointer to it in your app delegate and retrieve it using
BlahAppDelegate* delegate = [[UIApplication sharedApplication] delegate];
id bigObject = delegate.bigObject;
Since the app delegate will outlive the view controllers, you shouldn't have to worry about retain and release for it.
A singleton class should work similarly, as long as the singleton instance method (that retrieves the one created instance) calls retain on the instance when before it returns it. When the view is dealloc-ed, make sure you call release on the instance.

Related

How can I pass referece from an object in AppDelgate to ViewControllers

I created an App using a storyboard in Xcode. the App contains an UITabBarController (TBC) and some UIViewControllers (VC), controlled from the TBC.
In the AppDelegate a create an object (lets call it "myMidi") which will listen to incoming MIDI-Messages (CoreMidi). So I implement the interfaces of this myMidi-Object in my VC.
I connected the views to the TBC using the "Relationship" option in the Interface Builder (IB).
All VCs, created in the IB are a instance of my own VC Class. As i mentioned bevore, in this Class I implement the interface of the the myMidi-Object I created in the AppDelegate.
So every VC-instance holds an address of an myMidi-Object and need now the one and only reference which was created in AppDelegate.
So I am wondering how can I access to the current VC or the TBC which is displayed currently to pass this reference to my VC Class?
Or how else can I solve this issue. I guess I should do this somewhere in AppDelegate or should I hold the reference in the TBC too and pass it to every new VC when the VC will be created !?
If I understood correctly, you want your MyMidi class's current (only?) instance to be available to your VCs?
If you only ever have one Instance, consider making MyMidi a singleton class and give it a class method à la + (MyMidi *)sharedInstance; which always returns (and lazily initializes) the same object. That way, you can access it from anywhere.
See this question on how to implement a singleton in Cocoa/Cocoa Touch.
Use nsdefaults setObjec:forKey: to pass the object and get it where you want. Or make a property in appdelegate and access it through
AppDelegate* appDelegate = (TappAppDelegate*) [[UIApplication sharedApplication] delegate];
appDelegate.object = yourObject;

How to make a delegate object accessible throughout a ViewController

I'm trying to get an instance of my AppDelegate accessible to all methods in each ViewController that I have. If I try to declare it with other class variables I get Initializer Element is not a compile-time constant. If I declare it in a method within the ViewController however I am able to use it. I am trying to save integers and floats to properties I have set up in the AppDelegate (a big no-no I know, but this is a project for an introductory class and I'm not expected to get too advanced, especially since everything we've done so far is not compliant with the MVC paradigm). The app uses a toolbar to switch between views using the app's ViewController to load the other ViewControllers as subviews. I was going to put the AppDelegate declaration and update statements in the ViewDidUnload method of each view controller, but I'm not sure that the Views are unloaded whenever they are switched (they're switched by removing the current View from the SuperView and loading the new one as a Subview at index 0). What happens to the views that are not currently being viewed then? Is there a method that detects that that I could implement the AppDelegate declaration and updates into?
I guess ideally I'd like to be able to access the AppDelegate object in any method in my ViewControllers because I have a lot of quantities being updated throughout and would like to have those quantities updated in the AppDelegates values as soon as they happen, since I'm not sure what happens with a View is cleared from SuperView
Thanks in advance everyone
You can access your app delegate via [[UIApplication sharedApplication] delegate] from anywhere in your application.
You should never instantiate another copy of the object on your own. The system does this for you at startup.
As for detecting changes, you can override the viewDidDisappear method of UIViewController. (You're correct--in general, they will not be unloaded when switched, and viewDidUnload will not be called)

Core Data - Basic Questions

I would like to know how the following works in Objective-C
in my header file i have the following which is initialized from a different view controller
#interface UserLookup : UIViewController {
NSManagedObjectContext *referringObject;
}
and in my implementation file i have to pass this NSManagedObjectContext to 2 child view controller then does it make a difference which view controller is called first... and does the NSManagedObjectContext changes in any one of the child controller?
Regards
You don't really need to pass it around to every view controller where you will need Core Data access - just use
NSManagedObjectContext* moc = [(MyAppDelegateClass *)[[UIApplication sharedApplication] delegate] managedObjectContext];
managedObjectContext must be an accessible ivar of your app delegate.
It makes it conceptually similar too. There is one NSManagedObjectContext (in most uncomplicated apps, thought you can have multiples), owned by your app delegate. You don't ever retain or release it (except for when it is created in the app delegate, on first access if you are using Apple's template code, and when it is released in app delegate's dealloc.
ASFAIK it should not make a difference which viewController is used first. Think of the NSManagedObjectContext as a pointer to the physical datasource.
You can add and remove NSManagedObjects from the context. But these changes are only saved to disk when you call the save: method.
Does that help at all?
To use only one context is simple and works fine. But you can also create a new managed object context and pass it to the other view controller. Though the persistent store is only one, but you can have multiple contexts.
Each context have each undo manager, so you can control changes of managed objects in the context. You can save changes in only one context even if the other context has also some changes. After saving a context, you can merge the changes of two contexts by the following NSManagedObjectContext instance methods:
- (void)mergeChangesFromContextDidSaveNotification:(NSNotification *)notification
- (void)refreshObject:(NSManagedObject *)object mergeChanges:(BOOL)flag
Maybe this document helps you to understand more detail.
http://developer.apple.com/library/ios/#documentation/DataManagement/Conceptual/CoreDataSnippets/Articles/stack.html
And the CoreDataBooks Apple sample code uses the additional context.

How to properly pass NSArray / NSMutableArray from one UIViewController to another

An iphone app I'm working on is terminating periodically ... and I have a feeling it is because of how I'm accessing a shared NSArray amongst several view controllers. So ...
What is the best way to pass NSArray/NSMutableArray amongst several ViewControllers ... all of which can modify and/or set it to nil or whatever?
Thanks
There are two approaches, generally speaking.
In the first approach, when you instantiate your next view controller, you could set an array property to "inherit" from the current (soon-to-be previous or parent) view controller:
MyNextViewController *_myNextViewController = [[MyNextViewController alloc] initWithNibName:#"MyNextViewController" bundle:nil];
_myNextViewController.myViewControllerArray = self.myViewControllerArray;
...
In the second approach, you could create a myAppDelegateArray property in your application delegate, instantiating the array when the application initializes (or instantiated somewhere else, on demand).
You can then call the getter for this property from any class — including view controllers.
For example, within an instance of MyNextViewController, you might have a property called myViewControllerArray and you would set it as follows:
self.myViewControllerArray = [UIAppDelegate myAppDelegateArray];
You would add a #define statement somewhere in your application constants file, e.g.:
#define UIAppDelegate ((MyAppDelegate *)[UIApplication sharedApplication].delegate)
or use the full [UIApplication sharedApplication].delegate call, if you prefer.
As a general approach, people seem to prefer the app delegate approach, as it decentralizes access to the desired property.
With this approach, if you rearrange your view controllers or insert new view controllers into your VC hierarchy, you wouldn't need to debug child view controller properties inherited from parent view controllers, because a reference is always available from the app delegate.
you are probably not retaining it, it gets deallocated and you are trying to access it again. try to send a [myArray retain] where you are using it (in each of the controllers), and [myArray release] when you are done with it

how to get to appdelegate from viewcontrollers' value?

i know how to access appdelegate's value inside Viewcontroller like
YourDelegate *appDelegate = (YourDelegate *)[[UIApplication sharedApplication] delegate];
but i want simple method like this when i want to get value from viewcontroller to appdelegate(reverse order).....? any help...?
suppose if i have one method in appdelate. i want to get data value from view controller page,i want to use it in appdelegte.m file.......?
To address this question more generally...If you want to do anything with an object – send it a message (call a method on an object), access some property of an object, pass the object as a parameter to some other method – you need a reference to that object.
That means that, in your case, your AppDelegate needs a reference to the view controller you want to access some property of. If the view controller is allocated and initialized in your app delegate, this is as simple as storing a reference to said view controller in your delegate until you need to use it (using an instance variable or whatever). If it wasn't, then you need to do something else to get your app delegate a reference to the view controller – the steps to do this would depend on where and how the view controller was created. Without more specific details, I can't help you with those steps.
Model-View-Controller (MVC) Sidenote:
If you are following MVC design practices, a view controller (or any other controller class) is not the object that should be storing your state information or other application data. That job is supposed to be performed by a model object.
Make the method be a class method (declared with + (void) MyMethod: (int)myParameter) and call it from your app delegate like this: [MyOtherViewController MyMethod: myParameter].
This to call checkAppTheme method from AppDelegate.m :
[(AppDelegate *)[[UIApplication sharedApplication] delegate] checkAppTheme];
Don't miss to change (checkAppTheme) to your method in your AppDelegate.m
Good luck!