7

Possible Duplicate:
How or where should I store object instances that I require globally within my iOS app?

I have some global object (uses in almost all Application Screens) and mostly they are created right after application starts. I want to have access to this objects from all my ViewControllers (nothing else, only ViewControllers). Where to store it?

I think about @property in AppDelegate but i think (but I can be wrong) this is a ugly solution.

Objects can be quite complex, this is not a simple types.

Community
  • 1
  • 1
Jakub
  • 13,712
  • 17
  • 82
  • 139
  • 1
    possible duplicate of [How or where should I store object instances that I require globally within my iOS app?](http://stackoverflow.com/q/5721990/), [Global variable in iOS app](http://stackoverflow.com/q/9096712/), [Where do I create global variables?](http://stackoverflow.com/q/9593594/), [How can I save global variables in iOS](http://stackoverflow.com/q/9960982/), [iPhone Dev: global variables](http://stackoverflow.com/q/7368820/), [Global variables in ObjC](http://stackoverflow.com/q/1643467/), [Best way to keep global variables](http://stackoverflow.com/q/3456981/) – jscs Jul 18 '12 at 16:48

5 Answers5

10

You can make global objects accessible by placing them in a class with class methods for accessing global objects, implementing +(void)load to prepare these objects, and storing them in static variables.

Header:

@interface GlobalObjects
+(void)load;
+(MyObject1*)myObject1;
@end

Implementation:

#import "GlobalObjects.h"
static MyObject1* _myObject1 = nil;
@implementation GlobalObjects
+(void)load {
    _myObject1 = [[MyObject1 alloc] init];
}
+(MyObject1*)myObject1 {
    return myObject1;
}
@end

Usage:

MyObject1 *shared = [GlobalObjects myObject1];

You could also make the variable static inside its method for lazy initialization.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • I don't understand some part. If i have a GlobalObjects class i have to implement it into all my classes? If i set it as class method there is no need to create instances in classes? – Jakub Jul 18 '12 at 17:04
  • @SimpleMan All you need is to import `GlobalObjects.h`. Since all its methods are *class methods* (note the `+`) you do not need to instantiate `GlobalObjects`. The `+(void)load` method is called automatically when the class is loaded into cocoa runtime, so you do not need to call it either. – Sergey Kalinichenko Jul 18 '12 at 17:15
  • You mentioned that making the objects static uses lazy initialization, but don't all the objects get instantiated when any `[GlobalObjects ]` is accessed for the first time? If I'm understanding that correctly, is there a way to make objects independently lazy? Also, is this still the recommended way to have globally accessible objects? – Jake T. Apr 10 '17 at 20:27
  • 1
    @JakeT. As far as I know, the initialization has to happen at some time prior to the first access, but it wouldn't not necessarily happen immediately before the first access. The trick with the `static` that I mention in the last sentence of the answer is described [here](http://stackoverflow.com/a/11770303/335858). Another trick is [here](http://stackoverflow.com/q/5720029/335858), but it takes a little more code. – Sergey Kalinichenko Apr 10 '17 at 20:57
  • Thanks @dasblinkenlight, the second link ended up being most useful to me. Having the instance of the object that I could access rather than objects on a class seems most appropriate for my needs. – Jake T. Apr 11 '17 at 17:47
3

Yeah I use properties of the App Delegate, then access them by casting the sharedApplication delegate property.

__weak AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

Hope this helps,

Jonathan

Jonathan King
  • 1,528
  • 14
  • 25
1

@property in AppDelegate is a good solution. You could also use a singleton.

divol
  • 192
  • 7
1

You app delegate is fine if you just have a bunch of objects.

Otherwise you might build a sort of "model object" containing all of your global data.

Or, you might store them with Core Data, if they have any structure at all.

But, as I said, if you have just a couple of objects, the app delegate will just do fine.

sergio
  • 68,819
  • 11
  • 102
  • 123
  • What you mean by "if they have any structure at all". In my case this will be NSArray contains my own objects (not a simple types). – Jakub Jul 18 '12 at 16:59
  • I mean, Core Data is a data base, so basically, if they have a structure that would suggest building a data base. It was just to show a full set of options, so that you can better decide which option is better for you. The question is: how are you going to access the data? An NSArray if perfect and will allow you to access objects by their index; you could use an NSDictionary and then access each object by their "name" (the dictionary key)... for more help, possibly you should give more details about your objects... – sergio Jul 18 '12 at 17:09
1

if it's only used among view controllers, you might consider storing it in the highest level view controller which actually needs access to the shared object (when creating/pushing new controllers, set that reference counted property).

in this way, you might think of the master view controller populating the detail view controllers with their content/models.

that's really stepping away from qualification as (and burdens of) a global.

justin
  • 104,054
  • 14
  • 179
  • 226
  • This is good advice, but following this to every view controller i have to create another instance of objects. Am i right? I want to set this objects once and get access to them from any ViewController. – Jakub Jul 18 '12 at 17:01
  • @SimpleMan you would simply share the reference (to the `NSArray`) among VCs (View Controller). the array's elements would not be copied. you would need to declare new properties in your VCs for this array, but that's a lesser evil than a global `NSArray` on most days. envision it like sharing a document or model among VCs and their views. so, no, you do not need to create any additional objects (no new array, or its elements) -- but you do have to declare properties (storage) in your VCs for this shared object, and you would have to set that property when constructing/pushing the VC. – justin Jul 18 '12 at 17:21